@@ -4417,6 +4417,229 @@ def scatter(self, x, y, s=20, c='b', marker='o', cmap=None, norm=None,
44174417
44184418 scatter .__doc__ = cbook .dedent (scatter .__doc__ ) % martist .kwdocd
44194419
4420+ def hexbin (self , x , y , gridsize = 100 , bins = None ,
4421+ xscale = 'linear' , yscale = 'linear' ,
4422+ cmap = None , norm = None , vmin = None , vmax = None ,
4423+ alpha = 1.0 , linewidths = None , edgecolors = 'none' ,
4424+ ** kwargs ):
4425+ """
4426+ HEXBIN(x, y, gridsize = 100, bins = None,
4427+ xscale = 'linear', yscale = 'linear',
4428+ cmap=None, norm=None, vmin=None, vmax=None,
4429+ alpha=1.0, linewidths=None, edgecolors='none'
4430+ **kwargs)
4431+
4432+ Make a hexagonal binning plot of x versus y, where x, y are 1-D
4433+ sequences of the same length, N.
4434+
4435+ Either or both of x and y may be masked arrays, in which case all
4436+ masks will be combined and only unmasked points will be plotted.
4437+
4438+ * gridsize=100 : The number of hexagons in the x-direction. The
4439+ corresponding number of hexagons in the
4440+ y-direction is chosen such that the hexagons are
4441+ approximately regular.
4442+ Alternatively, gridsize can be a tuple with two
4443+ elements specifying the number of hexagons in
4444+ the x-direction and the y-direction.
4445+
4446+ * bins=None : If None, no binning is applied; the color of
4447+ each hexagon directly corresponds to its count
4448+ value.
4449+ bins='log' : Use a logarithmic scale for the color map.
4450+ Internally, log(count+1) is used to determine
4451+ the hexagon color.
4452+ bins=<integer> : Divide the counts in the specified number of
4453+ bins, and color the hexagons accordingly
4454+ bins=<a sequence of values> :
4455+ The values of the lower bound of the bins
4456+ to be used.
4457+
4458+ * xscale = 'linear' | 'log':
4459+ Use a logarithmic scale on the horizontal axis.
4460+
4461+ * yscale = 'linear' | 'log':
4462+ Use a logarithmic scale on the vertical axis.
4463+
4464+ Other keyword args; the color mapping and normalization arguments.
4465+
4466+ * cmap = cm.jet : a colors.Colormap instance from cm.
4467+ defaults to rc image.cmap
4468+
4469+ * norm = colors.Normalize() : colors.Normalize instance
4470+ is used to scale luminance data to 0,1.
4471+
4472+ * vmin=None and vmax=None : vmin and vmax are used in conjunction
4473+ with norm to normalize luminance data. If either are None, the
4474+ min and max of the color array C is used. Note if you pass a norm
4475+ instance, your settings for vmin and vmax will be ignored
4476+
4477+ * alpha =1.0 : the alpha value for the patches
4478+
4479+ * linewidths, if None, defaults to (lines.linewidth,). Note
4480+ that this is a tuple, and if you set the linewidths
4481+ argument you must set it as a sequence of floats, as
4482+ required by RegularPolyCollection -- see
4483+ collections.RegularPolyCollection for details
4484+
4485+ Optional kwargs control the Collection properties; in
4486+ particular:
4487+
4488+ edgecolors='none' : Draw the edges in the same color
4489+ as the fill color. This is the default, as
4490+ it avoids unsightly unpainted pixels
4491+ between the hexagons.
4492+ edgecolors=None : Draw the outlines in the default color.
4493+ edgecolors=<a matplotlib color arg or sequence of rgba tuples>
4494+ : Draw the outlines in the specified color.
4495+
4496+ Here are the standard descriptions of all the Collection kwargs:
4497+ %(Collection)s
4498+
4499+ The return value is a PolyCollection instance; use get_array() on
4500+ this PolyCollection to get the counts in each hexagon.
4501+ """
4502+
4503+ if not self ._hold : self .cla ()
4504+
4505+ self ._process_unit_info (xdata = x , ydata = y , kwargs = kwargs )
4506+
4507+ x , y = delete_masked_points (x , y )
4508+
4509+ # Set the size of the hexagon grid
4510+ if iterable (gridsize ):
4511+ nx , ny = gridsize
4512+ else :
4513+ nx = gridsize
4514+ ny = int (nx / math .sqrt (3 ))
4515+ # Count the number of data in each hexagon
4516+ x = npy .array (x , float )
4517+ y = npy .array (y , float )
4518+ if xscale == 'log' :
4519+ x = npy .log (x )
4520+ if yscale == 'log' :
4521+ y = npy .log (y )
4522+ xmin = min (x )
4523+ xmax = max (x )
4524+ ymin = min (y )
4525+ ymax = max (y )
4526+ # In the x-direction, the hexagons exactly cover the region from
4527+ # xmin to xmax. Need some padding to avoid roundoff errors.
4528+ width = xmax - xmin
4529+ padding = 1.e-9 * width
4530+ xmin -= padding
4531+ xmax += padding
4532+ sx = (xmax - xmin ) / nx
4533+ sy = (ymax - ymin ) / ny
4534+ x = (x - xmin )/ sx
4535+ y = (y - ymin )/ sy
4536+ ix1 = npy .round (x )
4537+ iy1 = npy .round (y )
4538+ ix2 = npy .floor (x )
4539+ iy2 = npy .floor (y )
4540+
4541+ nx1 = nx + 1
4542+ ny1 = ny + 1
4543+ nx2 = nx
4544+ ny2 = ny
4545+ n = nx1 * ny1 + nx2 * ny2
4546+ counts = npy .zeros (n )
4547+ lattice1 = counts [:nx1 * ny1 ]
4548+ lattice2 = counts [nx1 * ny1 :]
4549+ lattice1 .shape = (nx1 ,ny1 )
4550+ lattice2 .shape = (nx2 ,ny2 )
4551+
4552+ d1 = (x - ix1 )** 2 + 3.0 * (y - iy1 )** 2
4553+ d2 = (x - ix2 - 0.5 )** 2 + 3.0 * (y - iy2 - 0.5 )** 2
4554+
4555+ for i in xrange (len (x )):
4556+ if d1 [i ] < d2 [i ]:
4557+ lattice1 [ix1 [i ], iy1 [i ]]+= 1
4558+ else :
4559+ lattice2 [ix2 [i ], iy2 [i ]]+= 1
4560+
4561+ px = xmin + sx * npy .array ([ 0.5 , 0.5 , 0.0 , - 0.5 , - 0.5 , 0.0 ])
4562+ py = ymin + sy * npy .array ([- 0.5 , 0.5 ,1.0 , 0.5 , - 0.5 , - 1.0 ]) / 3.0
4563+
4564+ polygons = npy .zeros ((6 , n , 2 ), float )
4565+ polygons [:,:nx1 * ny1 ,0 ] = npy .repeat (npy .arange (nx1 ), ny1 )
4566+ polygons [:,:nx1 * ny1 ,1 ] = npy .array (range (ny1 ) * nx1 )
4567+ polygons [:,nx1 * ny1 :,0 ] = npy .repeat (npy .arange (nx2 ) + 0.5 , ny2 )
4568+ polygons [:,nx1 * ny1 :,1 ] = npy .array (range (ny2 ) * nx2 ) + 0.5
4569+
4570+ polygons = npy .transpose (polygons , axes = [1 ,0 ,2 ])
4571+ polygons [:,:,0 ] *= sx
4572+ polygons [:,:,1 ] *= sy
4573+ polygons [:,:,0 ] += px
4574+ polygons [:,:,1 ] += py
4575+
4576+ if xscale == 'log' :
4577+ polygons [:,:,0 ] = npy .exp (polygons [:,:,0 ])
4578+ xmin = math .exp (xmin )
4579+ xmax = math .exp (xmax )
4580+ self .set_xscale ('log' )
4581+ if yscale == 'log' :
4582+ polygons [:,:,1 ] = npy .exp (polygons [:,:,1 ])
4583+ ymin = math .exp (ymin )
4584+ ymax = math .exp (ymax )
4585+ self .set_yscale ('log' )
4586+
4587+ class HexagonBinCollection (mcoll .PolyCollection ):
4588+ """A HexagonBinCollection is a PolyCollection where the edge
4589+ colors are always kept equal to the fill colors"""
4590+ def update_scalarmappable (self ):
4591+ mcoll .PolyCollection .update_scalarmappable (self )
4592+ self ._edgecolors = self ._facecolors
4593+
4594+ if edgecolors == 'none' :
4595+ collection = HexagonBinCollection (
4596+ polygons ,
4597+ linewidths = linewidths ,
4598+ transOffset = self .transData ,
4599+ )
4600+ else :
4601+ collection = mcoll .PolyCollection (
4602+ polygons ,
4603+ edgecolors = edgecolors ,
4604+ linewidths = linewidths ,
4605+ transOffset = self .transData ,
4606+ )
4607+
4608+ # Transform the counts if needed
4609+ if bins == 'log' :
4610+ counts = npy .log (counts + 1 )
4611+ elif bins != None :
4612+ if not iterable (bins ):
4613+ minimum , maximum = min (counts ), max (counts )
4614+ bins -= 1 # one less edge than bins
4615+ bins = minimum + (maximum - minimum )* npy .arange (bins )/ bins
4616+ bins = npy .sort (bins )
4617+ counts = bins .searchsorted (counts )
4618+
4619+ if norm is not None : assert (isinstance (norm , mcolors .Normalize ))
4620+ if cmap is not None : assert (isinstance (cmap , mcolors .Colormap ))
4621+ collection .set_array (counts )
4622+ collection .set_cmap (cmap )
4623+ collection .set_norm (norm )
4624+ collection .set_alpha (alpha )
4625+ collection .update (kwargs )
4626+
4627+ if vmin is not None or vmax is not None :
4628+ collection .set_clim (vmin , vmax )
4629+ else :
4630+ collection .autoscale_None ()
4631+
4632+ corners = ((xmin , ymin ), (xmax , ymax ))
4633+ self .update_datalim ( corners )
4634+ self .autoscale_view ()
4635+
4636+ # add the collection last
4637+ self .add_collection (collection )
4638+ return collection
4639+
4640+ hexbin .__doc__ = cbook .dedent (hexbin .__doc__ ) % martist .kwdocd
4641+
4642+
44204643 def arrow (self , x , y , dx , dy , ** kwargs ):
44214644 """
44224645 Draws arrow on specified axis from (x,y) to (x+dx,y+dy).
0 commit comments