@@ -270,16 +270,41 @@ def draw(self, renderer):
270270if self .get_path_effects ():
271271for pe in self .get_path_effects ():
272272pe .draw_path_collection (renderer ,
273- gc ,transform .frozen (),paths ,self .get_transforms (),
274- offsets ,transOffset ,self .get_facecolor (),self .get_edgecolor (),
275- self ._linewidths ,self ._linestyles ,self ._antialiaseds ,self ._urls ,
273+ gc ,transform .frozen (),paths ,
274+ self .get_transforms (),offsets ,transOffset ,
275+ self .get_facecolor (),self .get_edgecolor (),
276+ self ._linewidths ,self ._linestyles ,
277+ self ._antialiaseds ,self ._urls ,
276278self ._offset_position )
277279else :
278- renderer .draw_path_collection (
279- gc ,transform .frozen (),paths ,self .get_transforms (),
280- offsets ,transOffset ,self .get_facecolor (),self .get_edgecolor (),
281- self ._linewidths ,self ._linestyles ,self ._antialiaseds ,self ._urls ,
282- self ._offset_position )
280+ trans = self .get_transforms ()
281+ facecolors = self .get_facecolor ()
282+ edgecolors = self .get_edgecolor ()
283+ if (len (paths )== 1 and len (trans )<= 1 and
284+ len (facecolors )== 1 and len (edgecolors )== 1 and
285+ len (self ._linewidths )== 1 and
286+ self ._linestyles == [(None ,None )]and
287+ len (self ._antialiaseds )== 1 and len (self ._urls )== 1 and
288+ self .get_hatch ()is None ):
289+ gc .set_foreground (tuple (edgecolors [0 ]))
290+ gc .set_linewidth (self ._linewidths [0 ])
291+ gc .set_linestyle (self ._linestyles [0 ])
292+ gc .set_antialiased (self ._antialiaseds [0 ])
293+ gc .set_url (self ._urls [0 ])
294+ if len (trans ):
295+ transform = (transforms .Affine2D (trans [0 ])+
296+ transform )
297+ renderer .draw_markers (
298+ gc ,paths [0 ],transform .frozen (),
299+ mpath .Path (offsets ),transOffset ,tuple (facecolors [0 ]))
300+ else :
301+ renderer .draw_path_collection (
302+ gc ,transform .frozen (),paths ,
303+ self .get_transforms (),offsets ,transOffset ,
304+ self .get_facecolor (),self .get_edgecolor (),
305+ self ._linewidths ,self ._linestyles ,
306+ self ._antialiaseds ,self ._urls ,
307+ self ._offset_position )
283308
284309gc .restore ()
285310renderer .close_group (self .__class__ .__name__ )
@@ -686,7 +711,31 @@ def update_from(self, other):
686711""" )
687712
688713
689- class PathCollection (Collection ):
714+ class _CollectionWithSizes (Collection ):
715+ """
716+ Base class for collections that have an array of sizes.
717+ """
718+ def get_sizes (self ):
719+ return self ._sizes
720+
721+ def set_sizes (self ,sizes ,dpi = 72.0 ):
722+ if sizes is None :
723+ self ._sizes = np .array ([])
724+ self ._transforms = np .empty ((0 ,3 ,3 ))
725+ else :
726+ self ._sizes = np .asarray (sizes )
727+ self ._transforms = np .zeros ((len (self ._sizes ),3 ,3 ))
728+ scale = np .sqrt (self ._sizes )* dpi / 72.0
729+ self ._transforms [:,0 ,0 ]= scale
730+ self ._transforms [:,1 ,1 ]= scale
731+ self ._transforms [:,2 ,2 ]= 1.0
732+
733+ def draw (self ,renderer ):
734+ self .set_sizes (self ._sizes ,self .figure .dpi )
735+ Collection .draw (self ,renderer )
736+
737+
738+ class PathCollection (_CollectionWithSizes ):
690739"""
691740 This is the most basic :class:`Collection` subclass.
692741 """
@@ -701,28 +750,16 @@ def __init__(self, paths, sizes=None, **kwargs):
701750
702751Collection .__init__ (self ,** kwargs )
703752self .set_paths (paths )
704- self ._sizes = sizes
753+ self .set_sizes ( sizes )
705754
706755def set_paths (self ,paths ):
707756self ._paths = paths
708757
709758def get_paths (self ):
710759return self ._paths
711760
712- def get_sizes (self ):
713- return self ._sizes
714-
715- @allow_rasterization
716- def draw (self ,renderer ):
717- if self ._sizes is not None :
718- self ._transforms = [
719- transforms .Affine2D ().scale (
720- (np .sqrt (x )* self .figure .dpi / 72.0 ))
721- for x in self ._sizes ]
722- return Collection .draw (self ,renderer )
723761
724-
725- class PolyCollection (Collection ):
762+ class PolyCollection (_CollectionWithSizes ):
726763@docstring .dedent_interpd
727764def __init__ (self ,verts ,sizes = None ,closed = True ,** kwargs ):
728765"""
@@ -744,7 +781,7 @@ def __init__(self, verts, sizes=None, closed=True, **kwargs):
744781 %(Collection)s
745782 """
746783Collection .__init__ (self ,** kwargs )
747- self ._sizes = sizes
784+ self .set_sizes ( sizes )
748785self .set_verts (verts ,closed )
749786
750787def set_verts (self ,verts ,closed = True ):
@@ -773,15 +810,6 @@ def set_verts(self, verts, closed=True):
773810
774811set_paths = set_verts
775812
776- @allow_rasterization
777- def draw (self ,renderer ):
778- if self ._sizes is not None :
779- self ._transforms = [
780- transforms .Affine2D ().scale (
781- (np .sqrt (x )* self .figure .dpi / 72.0 ))
782- for x in self ._sizes ]
783- return Collection .draw (self ,renderer )
784-
785813
786814class BrokenBarHCollection (PolyCollection ):
787815"""
@@ -830,7 +858,7 @@ def span_where(x, ymin, ymax, where, **kwargs):
830858return collection
831859
832860
833- class RegularPolyCollection (Collection ):
861+ class RegularPolyCollection (_CollectionWithSizes ):
834862"""Draw a collection of regular polygons with *numsides*."""
835863_path_generator = mpath .Path .unit_regular_polygon
836864
@@ -871,29 +899,18 @@ def __init__(self,
871899 )
872900 """
873901Collection .__init__ (self ,** kwargs )
874- self ._sizes = sizes
902+ self .set_sizes ( sizes )
875903self ._numsides = numsides
876904self ._paths = [self ._path_generator (numsides )]
877905self ._rotation = rotation
878906self .set_transform (transforms .IdentityTransform ())
879907
880- @allow_rasterization
881- def draw (self ,renderer ):
882- self ._transforms = [
883- transforms .Affine2D ().rotate (- self ._rotation ).scale (
884- (np .sqrt (x )* self .figure .dpi / 72.0 )/ np .sqrt (np .pi ))
885- for x in self ._sizes ]
886- return Collection .draw (self ,renderer )
887-
888908def get_numsides (self ):
889909return self ._numsides
890910
891911def get_rotation (self ):
892912return self ._rotation
893913
894- def get_sizes (self ):
895- return self ._sizes
896-
897914
898915class StarPolygonCollection (RegularPolyCollection ):
899916"""
@@ -1339,7 +1356,7 @@ def get_color(self):
13391356return self .get_colors ()[0 ]
13401357
13411358
1342- class CircleCollection (Collection ):
1359+ class CircleCollection (_CollectionWithSizes ):
13431360"""
13441361 A collection of circles, drawn using splines.
13451362 """
@@ -1352,24 +1369,10 @@ def __init__(self, sizes, **kwargs):
13521369 %(Collection)s
13531370 """
13541371Collection .__init__ (self ,** kwargs )
1355- self ._sizes = sizes
1372+ self .set_sizes ( sizes )
13561373self .set_transform (transforms .IdentityTransform ())
13571374self ._paths = [mpath .Path .unit_circle ()]
13581375
1359- def get_sizes (self ):
1360- "return sizes of circles"
1361- return self ._sizes
1362-
1363- @allow_rasterization
1364- def draw (self ,renderer ):
1365- # sizes is the area of the circle circumscribing the polygon
1366- # in points^2
1367- self ._transforms = [
1368- transforms .Affine2D ().scale (
1369- (np .sqrt (x )* self .figure .dpi / 72.0 )/ np .sqrt (np .pi ))
1370- for x in self ._sizes ]
1371- return Collection .draw (self ,renderer )
1372-
13731376
13741377class EllipseCollection (Collection ):
13751378"""
@@ -1416,7 +1419,6 @@ def _set_transforms(self):
14161419"""
14171420 Calculate transforms immediately before drawing.
14181421 """
1419- self ._transforms = []
14201422ax = self .axes
14211423fig = self .figure
14221424
@@ -1439,10 +1441,16 @@ def _set_transforms(self):
14391441else :
14401442raise ValueError ('unrecognized units: %s' % self ._units )
14411443
1442- _affine = transforms .Affine2D
1443- for x ,y ,a in zip (self ._widths ,self ._heights ,self ._angles ):
1444- trans = _affine ().scale (x * sc ,y * sc ).rotate (a )
1445- self ._transforms .append (trans )
1444+ self ._transforms = np .zeros ((len (self ._widths ),3 ,3 ))
1445+ widths = self ._widths * sc
1446+ heights = self ._heights * sc
1447+ sin_angle = np .cos (np .deg2rad (self ._angles ))
1448+ cos_angle = np .cos (np .deg2rad (self ._angles ))
1449+ self ._transforms [:,0 ,0 ]= widths * cos_angle
1450+ self ._transforms [:,0 ,1 ]= heights * - sin_angle
1451+ self ._transforms [:,1 ,0 ]= widths * sin_angle
1452+ self ._transforms [:,1 ,1 ]= heights * cos_angle
1453+ self ._transforms [:,2 ,2 ]= 1.0
14461454
14471455if self ._units == 'xy' :
14481456m = ax .transData .get_affine ().get_matrix ().copy ()