@@ -148,12 +148,11 @@ def set_3d_properties(self, z=0, zdir='z'):
148
148
@artist .allow_rasterization
149
149
def draw (self , renderer ):
150
150
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 ]
151
+ proj = self .axes .M .transform ([position3d , position3d + self ._dir_vec ])
152
+ dx = proj [1 ][0 ] - proj [0 ][0 ]
153
+ dy = proj [1 ][1 ] - proj [0 ][1 ]
155
154
angle = math .degrees (math .atan2 (dy , dx ))
156
- with cbook ._setattr_cm (self , _x = proj [0 ][0 ], _y = proj [1 ][ 0 ],
155
+ with cbook ._setattr_cm (self , _x = proj [0 ][0 ], _y = proj [0 ][ 1 ],
157
156
_rotation = _norm_text_angle (angle )):
158
157
mtext .Text .draw (self , renderer )
159
158
self .stale = False
@@ -267,8 +266,8 @@ def get_data_3d(self):
267
266
@artist .allow_rasterization
268
267
def draw (self , renderer ):
269
268
xs3d , ys3d , zs3d = self ._verts3d
270
- xs , ys , zs = proj3d . proj_transform ( xs3d , ys3d , zs3d , self . axes . M )
271
- self .set_data (xs , ys )
269
+ points = self . axes . M . transform ( np . column_stack (( xs3d , ys3d , zs3d )) )
270
+ self .set_data (points [:, 0 ], points [:, 1 ] )
272
271
super ().draw (renderer )
273
272
self .stale = False
274
273
@@ -349,11 +348,11 @@ class Collection3D(Collection):
349
348
350
349
def do_3d_projection (self ):
351
350
"""Project the points according to renderer matrix."""
352
- xyzs_list = [proj3d . proj_transform ( * vs . T , self .axes . M )
353
- for vs , _ in self . _3dverts_codes ]
354
- self . _paths = [ mpath . Path ( np . column_stack ([ xs , ys ]), cs )
355
- for ( xs , ys , _ ), ( _ , cs ) in zip (xyzs_list , self ._3dverts_codes )]
356
- zs = np .concatenate ([ zs for _ , _ , zs in xyzs_list ])
351
+ path_vertices = [self . axes . M . transform ( vs ) for vs , _ in self ._3dverts_codes ]
352
+ self . _paths = [ mpath . Path ( vertices [:, : 2 ], codes )
353
+ for ( vertices , ( _ , codes ) )
354
+ in zip (path_vertices , self ._3dverts_codes )]
355
+ zs = np .concatenate (path_vertices )[:, 2 ]
357
356
return zs .min () if len (zs ) else 1e9
358
357
359
358
@@ -390,15 +389,14 @@ def do_3d_projection(self):
390
389
"""
391
390
Project the points according to renderer matrix.
392
391
"""
393
- xyslist = [proj3d ._proj_trans_points (points , self .axes .M )
394
- for points in self ._segments3d ]
395
- segments_2d = [np .column_stack ([xs , ys ]) for xs , ys , zs in xyslist ]
392
+ segments_3d = [self .axes .M .transform (segment ) for segment in self ._segments3d ]
393
+ segments_2d = [segment [:, :2 ] for segment in segments_3d ]
396
394
LineCollection .set_segments (self , segments_2d )
397
395
398
396
# FIXME
399
397
minz = 1e9
400
- for xs , ys , zs in xyslist :
401
- minz = min (minz , min ( zs ) )
398
+ for segment in segments_3d :
399
+ minz = min (minz , segment [ 0 ][ 2 ], segment [ 1 ][ 2 ] )
402
400
return minz
403
401
404
402
@@ -456,12 +454,10 @@ def get_path(self):
456
454
return self ._path2d
457
455
458
456
def do_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
- return min (vzs )
457
+ segments = self .axes .M .transform (self ._segment3d )
458
+ self ._path2d = mpath .Path (segments [:, :2 ])
459
+
460
+ return min (segments [:, 2 ])
465
461
466
462
467
463
class PathPatch3D (Patch3D ):
@@ -503,12 +499,10 @@ def set_3d_properties(self, path, zs=0, zdir='z'):
503
499
self ._code3d = path .codes
504
500
505
501
def do_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
- return min (vzs )
502
+ segments = self .axes .M .transform (self ._segment3d )
503
+ self ._path2d = mpath .Path (segments [:, :2 ], self ._code3d )
504
+
505
+ return min (segments [:, 2 ])
512
506
513
507
514
508
def _get_patch_verts (patch ):
@@ -610,14 +604,13 @@ def set_3d_properties(self, zs, zdir):
610
604
self .stale = True
611
605
612
606
def do_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 ]))
607
+ points = self .axes .M .transform (np .column_stack (self ._offsets3d ))
608
+ super ().set_offsets (points [:, :2 ])
609
+
610
+ self ._vzs = points [:, 2 ]
618
611
619
- if vzs .size > 0 :
620
- return min (vzs )
612
+ if self . _vzs .size > 0 :
613
+ return min (self . _vzs )
621
614
else :
622
615
return np .nan
623
616
@@ -751,37 +744,31 @@ def set_depthshade(self, depthshade):
751
744
self .stale = True
752
745
753
746
def do_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 )
757
747
# Sort the points based on z coordinates
758
748
# Performance optimization: Create a sorted index array and reorder
759
749
# 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
750
+ points = self .axes .M .transform (np .column_stack (self ._offsets3d ))
751
+ z_markers_idx = self ._z_markers_idx = np .argsort (points [:, 2 ])[::- 1 ]
752
+ self ._vzs = points [:, 2 ]
762
753
763
754
# we have to special case the sizes because of code in collections.py
764
755
# as the draw method does
765
756
# self.set_sizes(self._sizes, self.figure.dpi)
766
757
# so we cannot rely on doing the sorting on the way out via get_*
767
-
768
758
if len (self ._sizes3d ) > 1 :
769
759
self ._sizes = self ._sizes3d [z_markers_idx ]
770
760
771
761
if len (self ._linewidths3d ) > 1 :
772
762
self ._linewidths = self ._linewidths3d [z_markers_idx ]
773
763
774
- PathCollection .set_offsets (self , np . column_stack (( vxs , vys )) )
764
+ PathCollection .set_offsets (self , points [:, : 2 ] )
775
765
776
766
# Re-order items
777
- vzs = vzs [z_markers_idx ]
778
- vxs = vxs [z_markers_idx ]
779
- vys = vys [z_markers_idx ]
767
+ points = points [z_markers_idx ]
780
768
781
769
# Store ordered offset for drawing purpose
782
- self ._offset_zordered = np .column_stack ((vxs , vys ))
783
-
784
- return np .min (vzs ) if vzs .size else np .nan
770
+ self ._offset_zordered = points [:, :2 ]
771
+ return np .min (self ._vzs ) if self ._vzs .size else np .nan
785
772
786
773
@contextmanager
787
774
def _use_zordered_offset (self ):
0 commit comments