@@ -217,23 +217,39 @@ def set_segments(self, segments):
217217 '''
218218 Set 3D segments
219219 '''
220- self ._segments3d = np .asanyarray (segments )
220+ self ._seg_sizes = [len (c ) for c in segments ]
221+ self ._segments3d = []
222+ if len (segments ) > 0 :
223+ # Store the points in a single array for easier projection
224+ n_segments = np .sum (self ._seg_sizes )
225+ # Put all segments in a big array
226+ self ._segments3d_data = np .vstack (segments )
227+ # Add a fourth dimension for quaternions
228+ self ._segments3d_data = np .hstack ([self ._segments3d_data ,
229+ np .ones ((n_segments , 1 ))])
230+
231+ # For coveniency, store a view of the array in the original shape
232+ cum_s = 0
233+ for s in self ._seg_sizes :
234+ self ._segments3d .append (
235+ self ._segments3d_data [cum_s :cum_s + s , :3 ])
236+ cum_s += s
221237 LineCollection .set_segments (self , [])
222238
223239 def do_3d_projection (self , renderer ):
224240 '''
225241 Project the points according to renderer matrix.
226242 '''
227- shape = self ._segments3d . shape
228- segments3d = np . transpose ( self . _segments3d , axes = [ 2 , 0 , 1 ])
229- segments3d = segments3d . reshape (( 3 , - 1 ))
230- # Pad ones
231- segments3d = np . vstack ([ segments3d , np . ones (( 1 , segments3d . shape [ 1 ]))])
232- xys = proj3d . proj_transform_vec ( segments3d , renderer . M )
233- xys = np . reshape (xys . T , shape )
234- segments_2d = xys [:, :, 0 : 2 ]
243+ if len ( self ._segments3d ) == 0 :
244+ return 1e9
245+ xys = proj3d . proj_transform_vec ( self . _segments3d_data . T , renderer . M ). T
246+ segments_2d = []
247+ cum_s = 0
248+ for s in self . _seg_sizes :
249+ segments_2d . append (xys [ cum_s : cum_s + s , : 2 ] )
250+ cum_s += s
235251 LineCollection .set_segments (self , segments_2d )
236- minz = np .min (xys [:, :, 2 ]) if xys . size > 0 else 1e9
252+ minz = np .min (xys [:, 2 ])
237253 return minz
238254
239255 def draw (self , renderer , project = False ):
@@ -301,7 +317,7 @@ def set_3d_properties(self, path, zs=0, zdir='z'):
301317
302318 def do_3d_projection (self , renderer ):
303319 # pad ones
304- s = np .vstack (self ._segmenta3d , np .ones (self ._segment3d .shape [1 ]))
320+ s = np .vstack (self ._segments3d , np .ones (self ._segments3d .shape [1 ]))
305321 vxyzis = proj3d .proj_transform_vec_clip (s , renderer .M )
306322 self ._path2d = mpath .Path (vxyzis [0 :2 ].T , self ._code3d )
307323 # FIXME: coloring
@@ -433,8 +449,10 @@ def set_3d_properties(self, zs, zdir):
433449 # Force the collection to initialize the face and edgecolors
434450 # just in case it is a scalarmappable with a colormap.
435451 self .update_scalarmappable ()
436- offsets = np .vstack (self .get_offsets (), np .ones (len (verts )) * zs )
437- self ._offsets3d = juggle_axes_vec (offsets , zdir )
452+ offsets = self .get_offsets ()
453+ offsets = np .hstack ([offsets ,
454+ (np .ones (len (offsets )) * zs )[:, np .newaxis ]])
455+ self ._offsets3d = juggle_axes_vec (offsets , zdir ).T
438456 self ._facecolor3d = self .get_facecolor ()
439457 self ._edgecolor3d = self .get_edgecolor ()
440458 self .stale = True
@@ -539,14 +557,16 @@ def set_zsort(self, zsort):
539557
540558 def get_vector (self , segments3d ):
541559 """Optimize points for projection"""
542- segments3d = np .asarray (segments3d )
543- # Segments 3d are given in shape (n_segments, segsize, 3)
544- self ._segsize = segments3d .shape [1 ]
545- # Flatten
546- xyz = segments3d .T .reshape ((3 , - 1 ))
547- # Add a fourth dimension with only ones
548- ones = np .ones (xyz .shape [1 ])
549- self ._vec = np .vstack ([xyz , ones ])
560+
561+ self ._seg_sizes = [len (c ) for c in segments3d ]
562+ self ._vec = []
563+ if len (segments3d ) > 0 :
564+ # Store the points in a single array for easier projection
565+ n_segments = np .sum (self ._seg_sizes )
566+ # Put all segments in a big array
567+ self ._vec = np .vstack (segments3d )
568+ # Add a fourth dimension for quaternions
569+ self ._vec = np .hstack ([self ._vec , np .ones ((n_segments , 1 ))]).T
550570
551571 def set_verts (self , verts , closed = True ):
552572 '''Set 3D vertices.'''
@@ -574,7 +594,7 @@ def set_3d_properties(self):
574594 self ._alpha3d = PolyCollection .get_alpha (self )
575595 self .stale = True
576596
577- def set_sort_zpos (self ,val ):
597+ def set_sort_zpos (self , val ):
578598 '''Set the position to use for z-sorting.'''
579599 self ._sort_zpos = val
580600 self .stale = True
@@ -588,9 +608,12 @@ def do_3d_projection(self, renderer):
588608 self .update_scalarmappable ()
589609 self ._facecolors3d = self ._facecolors
590610
591- xys = proj3d .proj_transform_vec (self ._vec , renderer .M )
592- xys = np .reshape (xys , (3 , self ._segsize , - 1 ))
593- xyzlist = xys .T
611+ xys = proj3d .proj_transform_vec (self ._vec , renderer .M ).T
612+ xyzlist = []
613+ cum_s = 0
614+ for s in self ._seg_sizes :
615+ xyzlist .append (xys [cum_s :cum_s + s , :3 ])
616+ cum_s += s
594617
595618 # This extra fuss is to re-order face / edge colors
596619 cface = self ._facecolors3d
@@ -605,11 +628,11 @@ def do_3d_projection(self, renderer):
605628 # if required sort by depth (furthest drawn first)
606629 if self ._zsort :
607630 z_argsort = np .argsort (
608- self ._zsortfunc (xyzlist [:, :, 2 ], axis = 1 ) )[::- 1 ]
631+ [ self ._zsortfunc (xyz [:, 2 ]) for xyz in xyzlist ] )[::- 1 ]
609632 else :
610633 raise ValueError ("whoops" )
611634
612- segments_2d = xyzlist [z_argsort , :, 0 :2 ]
635+ segments_2d = [ xyzlist [i ][ :, 0 :2 ] for i in z_argsort ]
613636 if self ._codes3d is not None :
614637 codes = self ._codes3d [z_argsort ]
615638 PolyCollection .set_verts_and_codes (self , segments_2d , codes )
0 commit comments