Revision: 5084
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5084&view=rev
Author: efiring
Date: 2008-04-28 00:24:33 -0700 (Mon, 28 Apr 2008)
Log Message:
-----------
Added hexbin axes method and pyplot function by Michiel de Hoon.
Tracker 1952339.
Modified Paths:
--------------
trunk/matplotlib/API_CHANGES
trunk/matplotlib/CHANGELOG
trunk/matplotlib/boilerplate.py
trunk/matplotlib/lib/matplotlib/axes.py
trunk/matplotlib/lib/matplotlib/pyplot.py
Modified: trunk/matplotlib/API_CHANGES
===================================================================
--- trunk/matplotlib/API_CHANGES 2008-04-28 01:59:05 UTC (rev 5083)
+++ trunk/matplotlib/API_CHANGES 2008-04-28 07:24:33 UTC (rev 5084)
@@ -1,3 +1,7 @@
+ New axes method and pyplot function, hexbin, is an alternative
+ to scatter for large datasets. It makes something like a
+ pcolor of a 2-D histogram, but uses hexagonal bins.
+
New kwarg, "symmetric", in MaxNLocator
allows one require an axis to be centered on zero.
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-04-28 01:59:05 UTC (rev 5083)
+++ trunk/matplotlib/CHANGELOG 2008-04-28 07:24:33 UTC (rev 5084)
@@ -1,3 +1,6 @@
+2008-04-27 Applied patch by Michiel de Hoon to add hexbin
+ axes method and pyplot function - EF
+
2008-04-25 Enforce python >= 2.4; remove subprocess build - EF
2008-04-25 Enforce the numpy requirement at build time - JDH
Modified: trunk/matplotlib/boilerplate.py
===================================================================
--- trunk/matplotlib/boilerplate.py 2008-04-28 01:59:05 UTC (rev 5083)
+++ trunk/matplotlib/boilerplate.py 2008-04-28 07:24:33 UTC (rev 5084)
@@ -63,6 +63,7 @@
'csd',
'errorbar',
'fill',
+ 'hexbin',
'hist',
'hlines',
'imshow',
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2008-04-28 01:59:05 UTC (rev
5083)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2008-04-28 07:24:33 UTC (rev
5084)
@@ -4417,6 +4417,229 @@
scatter.__doc__ = cbook.dedent(scatter.__doc__) % martist.kwdocd
+ def hexbin(self, x, y, gridsize = 100, bins = None,
+ xscale = 'linear', yscale = 'linear',
+ cmap=None, norm=None, vmin=None, vmax=None,
+ alpha=1.0, linewidths=None, edgecolors='none',
+ **kwargs):
+ """
+ HEXBIN(x, y, gridsize = 100, bins = None,
+ xscale = 'linear', yscale = 'linear',
+ cmap=None, norm=None, vmin=None, vmax=None,
+ alpha=1.0, linewidths=None, edgecolors='none'
+ **kwargs)
+
+ Make a hexagonal binning plot of x versus y, where x, y are 1-D
+ sequences of the same length, N.
+
+ Either or both of x and y may be masked arrays, in which case all
+ masks will be combined and only unmasked points will be plotted.
+
+ * gridsize=100 : The number of hexagons in the x-direction. The
+ corresponding number of hexagons in the
+ y-direction is chosen such that the hexagons are
+ approximately regular.
+ Alternatively, gridsize can be a tuple with two
+ elements specifying the number of hexagons in
+ the x-direction and the y-direction.
+
+ * bins=None : If None, no binning is applied; the color of
+ each hexagon directly corresponds to its count
+ value.
+ bins='log' : Use a logarithmic scale for the color map.
+ Internally, log(count+1) is used to determine
+ the hexagon color.
+ bins=<integer> : Divide the counts in the specified number of
+ bins, and color the hexagons accordingly
+ bins=<a sequence of values> :
+ The values of the lower bound of the bins
+ to be used.
+
+ * xscale = 'linear' | 'log':
+ Use a logarithmic scale on the horizontal axis.
+
+ * yscale = 'linear' | 'log':
+ Use a logarithmic scale on the vertical axis.
+
+ Other keyword args; the color mapping and normalization arguments.
+
+ * cmap = cm.jet : a colors.Colormap instance from cm.
+ defaults to rc image.cmap
+
+ * norm = colors.Normalize() : colors.Normalize instance
+ is used to scale luminance data to 0,1.
+
+ * vmin=None and vmax=None : vmin and vmax are used in conjunction
+ with norm to normalize luminance data. If either are None, the
+ min and max of the color array C is used. Note if you pass a norm
+ instance, your settings for vmin and vmax will be ignored
+
+ * alpha =1.0 : the alpha value for the patches
+
+ * linewidths, if None, defaults to (lines.linewidth,). Note
+ that this is a tuple, and if you set the linewidths
+ argument you must set it as a sequence of floats, as
+ required by RegularPolyCollection -- see
+ collections.RegularPolyCollection for details
+
+ Optional kwargs control the Collection properties; in
+ particular:
+
+ edgecolors='none' : Draw the edges in the same color
+ as the fill color. This is the default, as
+ it avoids unsightly unpainted pixels
+ between the hexagons.
+ edgecolors=None : Draw the outlines in the default color.
+ edgecolors=<a matplotlib color arg or sequence of rgba tuples>
+ : Draw the outlines in the specified color.
+
+ Here are the standard descriptions of all the Collection kwargs:
+ %(Collection)s
+
+ The return value is a PolyCollection instance; use get_array() on
+ this PolyCollection to get the counts in each hexagon.
+ """
+
+ if not self._hold: self.cla()
+
+ self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
+
+ x, y = delete_masked_points(x, y)
+
+ # Set the size of the hexagon grid
+ if iterable(gridsize):
+ nx, ny = gridsize
+ else:
+ nx = gridsize
+ ny = int(nx/math.sqrt(3))
+ # Count the number of data in each hexagon
+ x = npy.array(x, float)
+ y = npy.array(y, float)
+ if xscale=='log':
+ x = npy.log(x)
+ if yscale=='log':
+ y = npy.log(y)
+ xmin = min(x)
+ xmax = max(x)
+ ymin = min(y)
+ ymax = max(y)
+ # In the x-direction, the hexagons exactly cover the region from
+ # xmin to xmax. Need some padding to avoid roundoff errors.
+ width = xmax - xmin
+ padding = 1.e-9 * width
+ xmin -= padding
+ xmax += padding
+ sx = (xmax-xmin) / nx
+ sy = (ymax-ymin) / ny
+ x = (x-xmin)/sx
+ y = (y-ymin)/sy
+ ix1 = npy.round(x)
+ iy1 = npy.round(y)
+ ix2 = npy.floor(x)
+ iy2 = npy.floor(y)
+
+ nx1 = nx + 1
+ ny1 = ny + 1
+ nx2 = nx
+ ny2 = ny
+ n = nx1*ny1+nx2*ny2
+ counts = npy.zeros(n)
+ lattice1 = counts[:nx1*ny1]
+ lattice2 = counts[nx1*ny1:]
+ lattice1.shape = (nx1,ny1)
+ lattice2.shape = (nx2,ny2)
+
+ d1 = (x-ix1)**2 + 3.0 * (y-iy1)**2
+ d2 = (x-ix2-0.5)**2 + 3.0 * (y-iy2-0.5)**2
+
+ for i in xrange(len(x)):
+ if d1[i] < d2[i]:
+ lattice1[ix1[i], iy1[i]]+=1
+ else:
+ lattice2[ix2[i], iy2[i]]+=1
+
+ px = xmin + sx * npy.array([ 0.5, 0.5, 0.0, -0.5, -0.5, 0.0])
+ py = ymin + sy * npy.array([-0.5, 0.5 ,1.0, 0.5, -0.5, -1.0]) / 3.0
+
+ polygons = npy.zeros((6, n, 2), float)
+ polygons[:,:nx1*ny1,0] = npy.repeat(npy.arange(nx1), ny1)
+ polygons[:,:nx1*ny1,1] = npy.array(range(ny1) * nx1)
+ polygons[:,nx1*ny1:,0] = npy.repeat(npy.arange(nx2) + 0.5, ny2)
+ polygons[:,nx1*ny1:,1] = npy.array(range(ny2) * nx2) + 0.5
+
+ polygons = npy.transpose(polygons, axes=[1,0,2])
+ polygons[:,:,0] *= sx
+ polygons[:,:,1] *= sy
+ polygons[:,:,0] += px
+ polygons[:,:,1] += py
+
+ if xscale=='log':
+ polygons[:,:,0] = npy.exp(polygons[:,:,0])
+ xmin = math.exp(xmin)
+ xmax = math.exp(xmax)
+ self.set_xscale('log')
+ if yscale=='log':
+ polygons[:,:,1] = npy.exp(polygons[:,:,1])
+ ymin = math.exp(ymin)
+ ymax = math.exp(ymax)
+ self.set_yscale('log')
+
+ class HexagonBinCollection(mcoll.PolyCollection):
+ """A HexagonBinCollection is a PolyCollection where the edge
+ colors are always kept equal to the fill colors"""
+ def update_scalarmappable(self):
+ mcoll.PolyCollection.update_scalarmappable(self)
+ self._edgecolors = self._facecolors
+
+ if edgecolors=='none':
+ collection = HexagonBinCollection(
+ polygons,
+ linewidths = linewidths,
+ transOffset = self.transData,
+ )
+ else:
+ collection = mcoll.PolyCollection(
+ polygons,
+ edgecolors = edgecolors,
+ linewidths = linewidths,
+ transOffset = self.transData,
+ )
+
+ # Transform the counts if needed
+ if bins=='log':
+ counts = npy.log(counts+1)
+ elif bins!=None:
+ if not iterable(bins):
+ minimum, maximum = min(counts), max(counts)
+ bins-=1 # one less edge than bins
+ bins = minimum + (maximum-minimum)*npy.arange(bins)/bins
+ bins = npy.sort(bins)
+ counts = bins.searchsorted(counts)
+
+ if norm is not None: assert(isinstance(norm, mcolors.Normalize))
+ if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
+ collection.set_array(counts)
+ collection.set_cmap(cmap)
+ collection.set_norm(norm)
+ collection.set_alpha(alpha)
+ collection.update(kwargs)
+
+ if vmin is not None or vmax is not None:
+ collection.set_clim(vmin, vmax)
+ else:
+ collection.autoscale_None()
+
+ corners = ((xmin, ymin), (xmax, ymax))
+ self.update_datalim( corners)
+ self.autoscale_view()
+
+ # add the collection last
+ self.add_collection(collection)
+ return collection
+
+ hexbin.__doc__ = cbook.dedent(hexbin.__doc__) % martist.kwdocd
+
+
def arrow(self, x, y, dx, dy, **kwargs):
"""
Draws arrow on specified axis from (x,y) to (x+dx,y+dy).
Modified: trunk/matplotlib/lib/matplotlib/pyplot.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/pyplot.py 2008-04-28 01:59:05 UTC (rev
5083)
+++ trunk/matplotlib/lib/matplotlib/pyplot.py 2008-04-28 07:24:33 UTC (rev
5084)
@@ -1953,6 +1953,27 @@
# This function was autogenerated by boilerplate.py. Do not edit as
# changes will be lost
+def hexbin(*args, **kwargs):
+ # allow callers to override the hold state by passing hold=True|False
+ b = ishold()
+ h = kwargs.pop('hold', None)
+ if h is not None:
+ hold(h)
+ try:
+ ret = gca().hexbin(*args, **kwargs)
+ draw_if_interactive()
+ except:
+ hold(b)
+ raise
+ gci._current = ret
+ hold(b)
+ return ret
+if Axes.hexbin.__doc__ is not None:
+ hexbin.__doc__ = dedent(Axes.hexbin.__doc__) + """
+Additional kwargs: hold = [True|False] overrides default hold state"""
+
+# This function was autogenerated by boilerplate.py. Do not edit as
+# changes will be lost
def semilogx(*args, **kwargs):
# allow callers to override the hold state by passing hold=True|False
b = ishold()
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins