Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfcfe8b1

Browse files
committed
Convert existing mplot3d functions to use transforms
1 parenteb7676c commitfcfe8b1

File tree

3 files changed

+76
-98
lines changed

3 files changed

+76
-98
lines changed

‎lib/mpl_toolkits/mplot3d/art3d.py

Lines changed: 53 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
Collection,LineCollection,PolyCollection,PatchCollection,PathCollection)
2121
frommatplotlib.colorsimportNormalize
2222
frommatplotlib.patchesimportPatch
23-
from .importproj3d
2423

2524

2625
def_norm_angle(a):
@@ -148,12 +147,11 @@ def set_3d_properties(self, z=0, zdir='z'):
148147
@artist.allow_rasterization
149148
defdraw(self,renderer):
150149
position3d=np.array((self._x,self._y,self._z))
151-
proj=proj3d._proj_trans_points(
152-
[position3d,position3d+self._dir_vec],self.axes.M)
153-
dx=proj[0][1]-proj[0][0]
154-
dy=proj[1][1]-proj[1][0]
150+
proj=self.axes.M.transform([position3d,position3d+self._dir_vec])
151+
dx=proj[1][0]-proj[0][0]
152+
dy=proj[1][1]-proj[0][1]
155153
angle=math.degrees(math.atan2(dy,dx))
156-
withcbook._setattr_cm(self,_x=proj[0][0],_y=proj[1][0],
154+
withcbook._setattr_cm(self,_x=proj[0][0],_y=proj[0][1],
157155
_rotation=_norm_text_angle(angle)):
158156
mtext.Text.draw(self,renderer)
159157
self.stale=False
@@ -267,8 +265,8 @@ def get_data_3d(self):
267265
@artist.allow_rasterization
268266
defdraw(self,renderer):
269267
xs3d,ys3d,zs3d=self._verts3d
270-
xs,ys,zs=proj3d.proj_transform(xs3d,ys3d,zs3d,self.axes.M)
271-
self.set_data(xs,ys)
268+
points=self.axes.M.transform(np.column_stack((xs3d,ys3d,zs3d)))
269+
self.set_data(points[:,0],points[:,1])
272270
super().draw(renderer)
273271
self.stale=False
274272

@@ -349,11 +347,11 @@ class Collection3D(Collection):
349347

350348
defdo_3d_projection(self):
351349
"""Project the points according to renderer matrix."""
352-
xyzs_list= [proj3d.proj_transform(*vs.T,self.axes.M)
353-
forvs,_inself._3dverts_codes]
354-
self._paths= [mpath.Path(np.column_stack([xs,ys]),cs)
355-
for (xs,ys,_), (_,cs)inzip(xyzs_list,self._3dverts_codes)]
356-
zs=np.concatenate([zsfor_,_,zsinxyzs_list])
350+
path_vertices= [self.axes.M.transform(vs)forvs,_inself._3dverts_codes]
351+
self._paths= [mpath.Path(vertices[:, :2],codes)
352+
for (vertices, (_,codes))
353+
inzip(path_vertices,self._3dverts_codes)]
354+
zs=np.concatenate(path_vertices)[:,2]
357355
returnzs.min()iflen(zs)else1e9
358356

359357

@@ -390,15 +388,14 @@ def do_3d_projection(self):
390388
"""
391389
Project the points according to renderer matrix.
392390
"""
393-
xyslist= [proj3d._proj_trans_points(points,self.axes.M)
394-
forpointsinself._segments3d]
395-
segments_2d= [np.column_stack([xs,ys])forxs,ys,zsinxyslist]
391+
segments_3d= [self.axes.M.transform(segment)forsegmentinself._segments3d]
392+
segments_2d= [segment[:, :2]forsegmentinsegments_3d]
396393
LineCollection.set_segments(self,segments_2d)
397394

398395
# FIXME
399396
minz=1e9
400-
forxs,ys,zsinxyslist:
401-
minz=min(minz,min(zs))
397+
forsegmentinsegments_3d:
398+
minz=min(minz,segment[0][2],segment[1][2])
402399
returnminz
403400

404401

@@ -456,12 +453,10 @@ def get_path(self):
456453
returnself._path2d
457454

458455
defdo_3d_projection(self):
459-
s=self._segment3d
460-
xs,ys,zs=zip(*s)
461-
vxs,vys,vzs,vis=proj3d.proj_transform_clip(xs,ys,zs,
462-
self.axes.M)
463-
self._path2d=mpath.Path(np.column_stack([vxs,vys]))
464-
returnmin(vzs)
456+
segments=self.axes.M.transform(self._segment3d)
457+
self._path2d=mpath.Path(segments[:, :2])
458+
459+
returnmin(segments[:,2])
465460

466461

467462
classPathPatch3D(Patch3D):
@@ -503,12 +498,10 @@ def set_3d_properties(self, path, zs=0, zdir='z'):
503498
self._code3d=path.codes
504499

505500
defdo_3d_projection(self):
506-
s=self._segment3d
507-
xs,ys,zs=zip(*s)
508-
vxs,vys,vzs,vis=proj3d.proj_transform_clip(xs,ys,zs,
509-
self.axes.M)
510-
self._path2d=mpath.Path(np.column_stack([vxs,vys]),self._code3d)
511-
returnmin(vzs)
501+
segments=self.axes.M.transform(self._segment3d)
502+
self._path2d=mpath.Path(segments[:, :2],self._code3d)
503+
504+
returnmin(segments[:,2])
512505

513506

514507
def_get_patch_verts(patch):
@@ -610,14 +603,13 @@ def set_3d_properties(self, zs, zdir):
610603
self.stale=True
611604

612605
defdo_3d_projection(self):
613-
xs,ys,zs=self._offsets3d
614-
vxs,vys,vzs,vis=proj3d.proj_transform_clip(xs,ys,zs,
615-
self.axes.M)
616-
self._vzs=vzs
617-
super().set_offsets(np.column_stack([vxs,vys]))
606+
points=self.axes.M.transform(np.column_stack(self._offsets3d))
607+
super().set_offsets(points[:, :2])
618608

619-
ifvzs.size>0:
620-
returnmin(vzs)
609+
self._vzs=points[:,2]
610+
611+
ifself._vzs.size>0:
612+
returnmin(self._vzs)
621613
else:
622614
returnnp.nan
623615

@@ -751,37 +743,31 @@ def set_depthshade(self, depthshade):
751743
self.stale=True
752744

753745
defdo_3d_projection(self):
754-
xs,ys,zs=self._offsets3d
755-
vxs,vys,vzs,vis=proj3d.proj_transform_clip(xs,ys,zs,
756-
self.axes.M)
757746
# Sort the points based on z coordinates
758747
# Performance optimization: Create a sorted index array and reorder
759748
# points and point properties according to the index array
760-
z_markers_idx=self._z_markers_idx=np.argsort(vzs)[::-1]
761-
self._vzs=vzs
749+
points=self.axes.M.transform(np.column_stack(self._offsets3d))
750+
z_markers_idx=self._z_markers_idx=np.argsort(points[:,2])[::-1]
751+
self._vzs=points[:,2]
762752

763753
# we have to special case the sizes because of code in collections.py
764754
# as the draw method does
765755
# self.set_sizes(self._sizes, self.figure.dpi)
766756
# so we cannot rely on doing the sorting on the way out via get_*
767-
768757
iflen(self._sizes3d)>1:
769758
self._sizes=self._sizes3d[z_markers_idx]
770759

771760
iflen(self._linewidths3d)>1:
772761
self._linewidths=self._linewidths3d[z_markers_idx]
773762

774-
PathCollection.set_offsets(self,np.column_stack((vxs,vys)))
763+
PathCollection.set_offsets(self,points[:, :2])
775764

776765
# Re-order items
777-
vzs=vzs[z_markers_idx]
778-
vxs=vxs[z_markers_idx]
779-
vys=vys[z_markers_idx]
766+
points=points[z_markers_idx]
780767

781768
# Store ordered offset for drawing purpose
782-
self._offset_zordered=np.column_stack((vxs,vys))
783-
784-
returnnp.min(vzs)ifvzs.sizeelsenp.nan
769+
self._offset_zordered=points[:, :2]
770+
returnnp.min(self._vzs)ifself._vzs.sizeelsenp.nan
785771

786772
@contextmanager
787773
def_use_zordered_offset(self):
@@ -954,8 +940,7 @@ def get_vector(self, segments3d):
954940
xs,ys,zs=np.vstack(segments3d).T
955941
else:# vstack can't stack zero arrays.
956942
xs,ys,zs= [], [], []
957-
ones=np.ones(len(xs))
958-
self._vec=np.array([xs,ys,zs,ones])
943+
self._vec=np.array([xs,ys,zs])
959944

960945
indices= [0,*np.cumsum([len(segment)forsegmentinsegments3d])]
961946
self._segslices= [*map(slice,indices[:-1],indices[1:])]
@@ -1020,27 +1005,28 @@ def do_3d_projection(self):
10201005
self._facecolor3d=self._facecolors
10211006
ifself._edge_is_mapped:
10221007
self._edgecolor3d=self._edgecolors
1023-
txs,tys,tzs=proj3d._proj_transform_vec(self._vec,self.axes.M)
1024-
xyzlist= [(txs[sl],tys[sl],tzs[sl])forslinself._segslices]
1008+
1009+
verts=self.axes.M.transform(np.column_stack(self._vec))
1010+
verts_slices= [verts[sl]forslinself._segslices]
10251011

10261012
# This extra fuss is to re-order face / edge colors
10271013
cface=self._facecolor3d
10281014
cedge=self._edgecolor3d
1029-
iflen(cface)!=len(xyzlist):
1030-
cface=cface.repeat(len(xyzlist),axis=0)
1031-
iflen(cedge)!=len(xyzlist):
1015+
1016+
iflen(cface)!=len(verts_slices):
1017+
cface=cface.repeat(len(verts_slices),axis=0)
1018+
iflen(cedge)!=len(verts_slices):
10321019
iflen(cedge)==0:
10331020
cedge=cface
10341021
else:
1035-
cedge=cedge.repeat(len(xyzlist),axis=0)
1022+
cedge=cedge.repeat(len(verts_slices),axis=0)
10361023

1037-
ifxyzlist:
1038-
# sort by depth (furthest drawn first)
1024+
ifverts_slices:
10391025
z_segments_2d=sorted(
1040-
((self._zsortfunc(zs),np.column_stack([xs,ys]),fc,ec,idx)
1041-
foridx, ((xs,ys,zs),fc,ec)
1042-
inenumerate(zip(xyzlist,cface,cedge))),
1043-
key=lambdax:x[0],reverse=True)
1026+
((self._zsortfunc(verts[:,2]),verts[:, :2],fc,ec,idx)
1027+
foridx, (verts,fc,ec)
1028+
inenumerate(zip(verts_slices,cface,cedge))),
1029+
key=lambdax:x[0],reverse=True)
10441030

10451031
_,segments_2d,self._facecolors2d,self._edgecolors2d,idxs= \
10461032
zip(*z_segments_2d)
@@ -1061,14 +1047,12 @@ def do_3d_projection(self):
10611047

10621048
# Return zorder value
10631049
ifself._sort_zposisnotNone:
1064-
zvec=np.array([[0], [0], [self._sort_zpos], [1]])
1065-
ztrans=proj3d._proj_transform_vec(zvec,self.axes.M)
1066-
returnztrans[2][0]
1067-
eliftzs.size>0:
1050+
returnself.axes.M.transform([0,0,self._sort_zpos])[2]
1051+
eliflen(verts)>0:
10681052
# FIXME: Some results still don't look quite right.
10691053
# In particular, examine contourf3d_demo2.py
10701054
# with az = -54 and elev = -45.
1071-
returnnp.min(tzs)
1055+
returnnp.min(verts[:,2])
10721056
else:
10731057
returnnp.nan
10741058

‎lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from .importart3d
3636
from .importproj3d
3737
from .importaxis3d
38+
from .importtransform3d
3839

3940

4041
@_docstring.interpd
@@ -158,8 +159,8 @@ def __init__(
158159
super().set_axis_off()
159160
# Enable drawing of axes by Axes3D class
160161
self.set_axis_on()
161-
self.M=None
162-
self.invM=None
162+
self.M=mtransforms.IdentityTransform(dims=3)
163+
self.invM=mtransforms.IdentityTransform(dims=3)
163164

164165
self._view_margin=1/48# default value to match mpl3.8
165166
self.autoscale_view()
@@ -236,7 +237,7 @@ def _transformed_cube(self, vals):
236237
(maxx,miny,maxz),
237238
(maxx,maxy,maxz),
238239
(minx,maxy,maxz)]
239-
returnproj3d._proj_points(xyzs,self.M)
240+
returnself.M.transform(xyzs)
240241

241242
defset_aspect(self,aspect,adjustable=None,anchor=None,share=False):
242243
"""
@@ -423,7 +424,7 @@ def draw(self, renderer):
423424

424425
# add the projection matrix to the renderer
425426
self.M=self.get_proj()
426-
self.invM=np.linalg.inv(self.M)
427+
self.invM=self.M.inverted()
427428

428429
collections_and_patches= (
429430
artistforartistinself._children
@@ -1200,12 +1201,8 @@ def get_proj(self):
12001201

12011202
# Transform to uniform world coordinates 0-1, 0-1, 0-1
12021203
box_aspect=self._roll_to_vertical(self._box_aspect)
1203-
worldM=proj3d.world_transformation(
1204-
*self.get_xlim3d(),
1205-
*self.get_ylim3d(),
1206-
*self.get_zlim3d(),
1207-
pb_aspect=box_aspect,
1208-
)
1204+
worldM=transform3d.WorldTransform(*self.get_xlim3d(),*self.get_ylim3d(),
1205+
*self.get_zlim3d(),pb_aspect=box_aspect)
12091206

12101207
# Look into the middle of the world coordinates:
12111208
R=0.5*box_aspect
@@ -1238,21 +1235,18 @@ def get_proj(self):
12381235
# Generate the view and projection transformation matrices
12391236
ifself._focal_length==np.inf:
12401237
# Orthographic projection
1241-
viewM=proj3d._view_transformation_uvw(u,v,w,eye)
1242-
projM=proj3d._ortho_transformation(-self._dist,self._dist)
1238+
viewM=transform3d.ViewTransform(u,v,w,eye)
1239+
projM=transform3d.OrthographicTransform(-self._dist,self._dist)
12431240
else:
12441241
# Perspective projection
12451242
# Scale the eye dist to compensate for the focal length zoom effect
12461243
eye_focal=R+self._dist*ps*self._focal_length
1247-
viewM=proj3d._view_transformation_uvw(u,v,w,eye_focal)
1248-
projM=proj3d._persp_transformation(-self._dist,
1249-
self._dist,
1250-
self._focal_length)
1244+
viewM=transform3d.ViewTransform(u,v,w,eye_focal)
1245+
projM=transform3d.PerspectiveTransform(-self._dist,self._dist,
1246+
self._focal_length)
12511247

12521248
# Combine all the transformation matrices to get the final projection
1253-
M0=np.dot(viewM,worldM)
1254-
M=np.dot(projM,M0)
1255-
returnM
1249+
returnworldM+viewM+projM
12561250

12571251
defmouse_init(self,rotate_btn=1,pan_btn=2,zoom_btn=3):
12581252
"""
@@ -1459,7 +1453,7 @@ def _calc_coord(self, xv, yv, renderer=None):
14591453
zv=-1/self._focal_length
14601454

14611455
# Convert point on view plane to data coordinates
1462-
p1=np.array(proj3d.inv_transform(xv,yv,zv,self.invM)).ravel()
1456+
p1=self.invM.transform([xv,yv,zv])
14631457

14641458
# Get the vector from the camera to the point on the view plane
14651459
vec=self._get_camera_loc()-p1

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp