@@ -78,9 +78,9 @@ def __init__(self,
78
78
** kwargs
79
79
):
80
80
"""
81
- Create a PatchCollection
81
+ Create a Collection
82
82
83
- %(PatchCollection )s
83
+ %(Collection )s
84
84
"""
85
85
artist .Artist .__init__ (self )
86
86
cm .ScalarMappable .__init__ (self , norm , cmap )
@@ -103,8 +103,9 @@ def __init__(self,
103
103
self ._uniform_offsets = None
104
104
self ._offsets = npy .zeros ((1 , 2 ))
105
105
if offsets is not None :
106
- # if len(offsets.shape) == 1:
107
- # offsets = offsets[npy.newaxis,:] # Make it Nx2.
106
+ offsets = npy .asarray (offsets , npy .float_ )
107
+ if len (offsets .shape ) == 1 :
108
+ offsets = offsets [npy .newaxis ,:] # Make it Nx2.
108
109
if transOffset is not None :
109
110
Affine2D = transforms .Affine2D
110
111
self ._offsets = offsets
@@ -171,7 +172,10 @@ def draw(self, renderer):
171
172
if not transform .is_affine :
172
173
paths = [transform .transform_path_non_affine (path ) for path in paths ]
173
174
transform = transform .get_affine ()
174
-
175
+ if not transOffset .is_affine :
176
+ offsets = transOffset .transform_non_affine (offsets )
177
+ transOffset = transOffset .get_affine ()
178
+
175
179
renderer .draw_path_collection (
176
180
transform , self .clipbox , clippath , clippath_trans ,
177
181
paths , self .get_transforms (),
@@ -353,7 +357,7 @@ def update_scalarmappable(self):
353
357
#print 'update_scalarmappable: self._A', self._A
354
358
if self ._A is None : return
355
359
if len (self ._A .shape )> 1 :
356
- raise ValueError ('PatchCollections can only map rank 1 arrays' )
360
+ raise ValueError ('Collections can only map rank 1 arrays' )
357
361
if len (self ._facecolors ):
358
362
self ._facecolors = self .to_rgba (self ._A , self ._alpha )
359
363
else :
@@ -410,32 +414,44 @@ class QuadMesh(Collection):
410
414
(0, 2) .. (0, meshWidth), (1, 0), (1, 1), and so on.
411
415
"""
412
416
def __init__ (self , meshWidth , meshHeight , coordinates , showedges ):
417
+ Path = path .Path
418
+
413
419
Collection .__init__ (self )
414
420
self ._meshWidth = meshWidth
415
421
self ._meshHeight = meshHeight
416
422
self ._coordinates = coordinates
417
423
self ._showedges = showedges
418
-
419
- def get_verts (self , dataTrans = None ):
420
- return self ._coordinates ;
424
+
425
+ # MGDTODO: Numpify
426
+ coordinates = coordinates .reshape ((meshHeight + 1 , meshWidth + 1 , 2 ))
427
+ c = coordinates
428
+ paths = []
429
+ # We could let the Path constructor generate the codes for us,
430
+ # but this is faster, since we know they'll always be the same
431
+ codes = npy .array ([Path .MOVETO , Path .LINETO , Path .LINETO , Path .LINETO ])
432
+ for m in xrange (meshHeight ):
433
+ for n in xrange (meshWidth ):
434
+ paths .append (Path (
435
+ [c [m , n ],
436
+ c [m , n + 1 ],
437
+ c [m + 1 , n + 1 ],
438
+ c [m + 1 , n ]],
439
+ codes ))
440
+ self ._paths = paths
441
+
442
+ def get_paths (self , dataTrans = None ):
443
+ return self ._paths
421
444
422
445
def draw (self , renderer ):
423
- # does not call update_scalarmappable, need to update it
424
- # when creating/changing ****** Why not? speed?
425
- if not self .get_visible (): return
426
- transform = self .get_transform ()
427
- transoffset = self ._transOffset
428
- transform .freeze ()
429
- transoffset .freeze ()
430
- #print 'QuadMesh draw'
431
446
self .update_scalarmappable () #######################
432
447
433
- renderer .draw_quad_mesh ( self ._meshWidth , self ._meshHeight ,
434
- self ._facecolors , self ._coordinates [:,0 ],
435
- self ._coordinates [:, 1 ], self .clipbox , transform ,
436
- self ._offsets , transoffset , self ._showedges )
437
- transform .thaw ()
438
- transoffset .thaw ()
448
+ self ._linewidths = (1 ,)
449
+ if self ._showedges :
450
+ self ._edgecolors = npy .array ([[0.0 , 0.0 , 0.0 , 1.0 ]], npy .float_ )
451
+ else :
452
+ self ._edgecolors = self ._facecolors
453
+
454
+ Collection .draw (self , renderer )
439
455
440
456
class PolyCollection (Collection ):
441
457
def __init__ (self , verts , ** kwargs ):
@@ -476,6 +492,8 @@ def __init__(self, xranges, yrange, **kwargs):
476
492
__init__ .__doc__ = cbook .dedent (__init__ .__doc__ ) % artist .kwdocd
477
493
478
494
class RegularPolyCollection (Collection ):
495
+ _path_generator = path .Path .unit_regular_polygon
496
+
479
497
def __init__ (self ,
480
498
dpi ,
481
499
numsides ,
@@ -514,18 +532,16 @@ def __init__(self,
514
532
offsets = offsets,
515
533
transOffset = ax.transData,
516
534
)
517
-
518
-
519
535
"""
520
536
Collection .__init__ (self ,** kwargs )
521
537
self ._sizes = sizes
522
538
self ._dpi = dpi
523
- self ._paths = [path . Path . unit_regular_polygon (numsides )]
539
+ self ._paths = [self . _path_generator (numsides )]
524
540
# sizes is the area of the circle circumscribing the polygon
525
541
# in points^2
526
542
self ._transforms = [
527
- transforms .Affine2D ().rotate (rotation ).scale (
528
- (math .sqrt (x ) * self ._dpi / 72.0 ) * ( 1.0 / math .sqrt (math .pi ) ))
543
+ transforms .Affine2D ().rotate (- rotation ).scale (
544
+ (math .sqrt (x ) * self ._dpi / 72.0 ) / math .sqrt (math .pi ))
529
545
for x in sizes ]
530
546
self .set_transform (transforms .IdentityTransform ())
531
547
@@ -554,72 +570,13 @@ def get_transformed_patches(self):
554
570
555
571
556
572
class StarPolygonCollection (RegularPolyCollection ):
557
- def __init__ (self ,
558
- dpi ,
559
- numsides ,
560
- rotation = 0 ,
561
- sizes = (1 ,),
562
- ** kwargs ):
563
- """
564
- Draw a regular star like Polygone with numsides.
565
-
566
- * dpi is the figure dpi instance, and is required to do the
567
- area scaling.
568
-
569
- * numsides: the number of sides of the polygon
570
-
571
- * sizes gives the area of the circle circumscribing the
572
- regular polygon in points^2
573
-
574
- * rotation is the rotation of the polygon in radians
575
-
576
- %(Collection)s
577
- """
578
-
579
- RegularPolyCollection .__init__ (self , dpi , numsides , rotation , sizes , ** kwargs )
580
- __init__ .__doc__ = cbook .dedent (__init__ .__doc__ ) % artist .kwdocd
581
-
582
- def _update_verts (self ):
583
- scale = 1.0 / math .sqrt (math .pi )
584
- ns2 = self .numsides * 2
585
- r = scale * npy .ones (ns2 )
586
- r [1 ::2 ] *= 0.5
587
- theta = (math .pi / self .numsides )* npy .arange (ns2 ) + self .rotation
588
- self ._verts = zip ( r * npy .sin (theta ), r * npy .cos (theta ) )
589
-
573
+ _path_generator = path .Path .unit_regular_star
574
+
575
+
590
576
class AsteriskPolygonCollection (RegularPolyCollection ):
591
- def __init__ (self ,
592
- dpi ,
593
- numsides ,
594
- rotation = 0 ,
595
- sizes = (1 ,),
596
- ** kwargs ):
597
- """
598
- Draw a regular asterisk Polygone with numsides spikes.
599
-
600
- * dpi is the figure dpi instance, and is required to do the
601
- area scaling.
602
-
603
- * numsides: the number of spikes of the polygon
604
-
605
- * sizes gives the area of the circle circumscribing the
606
- regular polygon in points^2
607
-
608
- * rotation is the rotation of the polygon in radians
609
-
610
- %(Collection)s
611
- """
612
-
613
- RegularPolyCollection .__init__ (self , dpi , numsides , rotation , sizes , ** kwargs )
614
- __init__ .__doc__ = cbook .dedent (__init__ .__doc__ ) % artist .kwdocd
615
-
616
- def _update_verts (self ):
617
- scale = 1.0 / math .sqrt (math .pi )
618
- r = scale * npy .ones (self .numsides * 2 )
619
- r [1 ::2 ] = 0
620
- theta = (math .pi / self .numsides )* npy .arange (2 * self .numsides ) + self .rotation
621
- self ._verts = zip ( r * npy .sin (theta ), r * npy .cos (theta ) )
622
-
577
+ _path_generator = path .Path .unit_regular_asterisk
578
+
579
+
623
580
class LineCollection (Collection , cm .ScalarMappable ):
624
581
"""
625
582
All parameters must be sequences or scalars; if scalars, they will
0 commit comments