Revision: 4377
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4377&view=rev
Author: efiring
Date: 2007-11-18 11:06:49 -0800 (Sun, 18 Nov 2007)
Log Message:
-----------
Add experimental "pcolorfast" for fast interactive pcolor plots
This will need more discussion and work, but it illustrates
the potential for very fast pcolor-type plotting with all
three grid types: uniform, irregular but rectilinear, and
general quadrilateral.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/axes.py
trunk/matplotlib/lib/matplotlib/image.py
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2007-11-18 19:02:55 UTC (rev
4376)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2007-11-18 19:06:49 UTC (rev
4377)
@@ -3706,8 +3706,8 @@
xs = [thisx for thisx, b in zip(xs, mask) if b]
ys = [thisy for thisy, b in zip(ys, mask) if b]
return xs, ys
-
+
if capsize > 0:
plot_kw = {
'ms':2*capsize,
@@ -3733,16 +3733,16 @@
# can't use numpy logical indexing since left and
# y are lists
leftlo, ylo = xywhere(left, y, xlolims)
-
+
caplines.extend( self.plot(leftlo, ylo, ls='None',
marker=mlines.CARETLEFT, **plot_kw) )
xlolims = ~xlolims
- leftlo, ylo = xywhere(left, y, xlolims)
+ leftlo, ylo = xywhere(left, y, xlolims)
caplines.extend( self.plot(leftlo, ylo, 'k|', **plot_kw) )
else:
caplines.extend( self.plot(left, y, 'k|', **plot_kw) )
if xuplims.any():
-
+
rightup, yup = xywhere(right, y, xuplims)
caplines.extend( self.plot(rightup, yup, ls='None',
marker=mlines.CARETRIGHT, **plot_kw) )
xuplims = ~xuplims
@@ -3775,7 +3775,7 @@
if uplims.any():
xup, upperup = xywhere(x, upper, uplims)
-
+
caplines.extend( self.plot(xup, upperup, ls='None',
marker=mlines.CARETUP, **plot_kw) )
uplims = ~uplims
xup, upperup = xywhere(x, upper, uplims)
@@ -4762,6 +4762,177 @@
return collection
pcolormesh.__doc__ = cbook.dedent(pcolormesh.__doc__) % martist.kwdocd
+ def pcolorfast(self, *args, **kwargs):
+ """
+ Experimental; this is a version of pcolor that
+ does not draw lines, that provides the fastest
+ possible rendering with the Agg backend, and that
+ can handle any quadrilateral grid.
+
+ pcolor(*args, **kwargs): pseudocolor plot of a 2-D array
+
+ Function signatures
+
+ pcolor(C, **kwargs)
+ pcolor(xr, yr, C, **kwargs)
+ pcolor(x, y, C, **kwargs)
+ pcolor(X, Y, C, **kwargs)
+
+ C is the 2D array of color values corresponding to quadrilateral
+ cells. Let (nr, nc) be its shape. C may be a masked array.
+
+ pcolor(C, **kwargs) is equivalent to
+ pcolor([0,nc], [0,nr], C, **kwargs)
+
+ xr, yr specify the ranges of x and y corresponding to the rectangular
+ region bounding C. If xr = [x0, x1] and yr = [y0,y1] then
+ x goes from x0 to x1 as the second index of C goes from 0 to nc,
+ etc. (x0, y0) is the outermost corner of cell (0,0), and (x1, y1)
+ is the outermost corner of cell (nr-1, nc-1). All cells are
+ rectangles of the same size. This is the fastest version.
+
+ x, y are 1D arrays of length nc+1 and nr+1, respectively, giving
+ the x and y boundaries of the cells. Hence the cells are
+ rectangular but the grid may be nonuniform. The speed is
+ intermediate. (The grid is checked, and if found to be
+ uniform the fast version is used.)
+
+ X and Y are 2D arrays with shape (nr+1, nc+1) that specify
+ the (x,y) coordinates of the corners of the colored
+ quadrilaterals; the quadrilateral for C[i,j] has corners at
+ (X[i,j],Y[i,j]), (X[i,j+1],Y[i,j+1]), (X[i+1,j],Y[i+1,j]),
+ (X[i+1,j+1],Y[i+1,j+1]). The cells need not be rectangular.
+ This is the most general, but the slowest to render. It may
+ produce faster and more compact output using ps, pdf, and
+ svg backends, however.
+
+ Note that the the column index corresponds to the x-coordinate,
+ and the row index corresponds to y; for details, see
+ the "Grid Orientation" section below.
+
+ Optional keyword args are shown with their defaults below (you must
+ use kwargs for these):
+
+ * cmap = cm.jet : a cm Colormap instance from cm
+
+ * norm = Normalize() : mcolors.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. If you pass a norm
+ instance, vmin and vmax will be None
+
+ * alpha=1.0 : the alpha blending value
+
+ Return value is an image if a regular or rectangular grid
+ is specified, and a QuadMesh collection in the general
+ quadrilateral case.
+
+ """
+
+ if not self._hold: self.cla()
+
+ alpha = kwargs.pop('alpha', 1.0)
+ norm = kwargs.pop('norm', None)
+ cmap = kwargs.pop('cmap', None)
+ vmin = kwargs.pop('vmin', None)
+ vmax = kwargs.pop('vmax', None)
+ if norm is not None: assert(isinstance(norm, mcolors.Normalize))
+ if cmap is not None: assert(isinstance(cmap, mcolors.Colormap))
+
+ C = args[-1]
+ nr, nc = C.shape
+ if len(args) == 1:
+ style = "image"
+ x = [0, nc+1]
+ y = [0, nr+1]
+ elif len(args) == 3:
+ x, y = args[:2]
+ x = npy.asarray(x)
+ y = npy.asarray(y)
+ if x.ndim == 1 and y.ndim == 1:
+ if x.size == 2 and y.size == 2:
+ style = "image"
+ else:
+ dx = npy.diff(x)
+ dy = npy.diff(y)
+ if (npy.ptp(dx) < 0.01*npy.abs(dx.mean()) and
+ npy.ptp(dy) < 0.01*npy.abs(dy.mean())):
+ style = "image"
+ style = "pcolorimage"
+ elif x.ndim == 2 and y.ndim == 2:
+ style = "quadmesh"
+ else:
+ raise TypeError("arguments do not match valid signatures")
+ else:
+ raise TypeError("need 1 argument or 3 arguments")
+
+ if style == "quadmesh":
+
+ # convert to one dimensional arrays
+ # This should also be moved to the QuadMesh class
+ C = ma.ravel(C) # data point in each cell is value at lower left
corner
+ X = x.ravel()
+ Y = y.ravel()
+ Nx = nc+1
+ Ny = nr+1
+
+ # The following needs to be cleaned up; the renderer
+ # requires separate contiguous arrays for X and Y,
+ # but the QuadMesh class requires the 2D array.
+ coords = npy.empty(((Nx * Ny), 2), npy.float64)
+ coords[:, 0] = X
+ coords[:, 1] = Y
+
+ # The QuadMesh class can also be changed to
+ # handle relevant superclass kwargs; the initializer
+ # should do much more than it does now.
+ collection = mcoll.QuadMesh(nc, nr, coords, 0)
+ collection.set_alpha(alpha)
+ collection.set_array(C)
+ collection.set_cmap(cmap)
+ collection.set_norm(norm)
+ self.add_collection(collection)
+ xl, xr, yb, yt = X.min(), X.max(), Y.min(), Y.max()
+ ret = collection
+
+ else:
+ # One of the image styles:
+ xl, xr, yb, yt = x[0], x[-1], y[0], y[-1]
+ if style == "image":
+
+ im = mimage.AxesImage(self, cmap, norm,
+ interpolation='nearest',
+ origin='lower',
+ extent=(xl, xr, yb, yt),
+ **kwargs)
+ im.set_data(C)
+ im.set_alpha(alpha)
+ self.images.append(im)
+ ret = im
+
+ if style == "pcolorimage":
+ im = mimage.PcolorImage(self, x, y, C,
+ cmap=cmap,
+ norm=norm,
+ alpha=alpha,
+ **kwargs)
+ self.images.append(im)
+ ret = im
+
+ self._set_artist_props(ret)
+ if vmin is not None or vmax is not None:
+ ret.set_clim(vmin, vmax)
+ else:
+ ret.autoscale_None()
+ self.update_datalim(npy.array([[xl, yb], [xr, yt]]))
+ self.autoscale_view(tight=True)
+ return ret
+
+
+
+
def contour(self, *args, **kwargs):
kwargs['filled'] = False
return mcontour.ContourSet(self, *args, **kwargs)
@@ -4822,14 +4993,14 @@
ticks on bottom and the returned axes will have ticks on the
top
"""
-
+
ax2 = self.figure.add_axes(self.get_position(), sharey=self,
frameon=False)
ax2.xaxis.tick_top()
ax2.xaxis.set_label_position('top')
self.xaxis.tick_bottom()
return ax2
-
+
#### Data analysis
Modified: trunk/matplotlib/lib/matplotlib/image.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/image.py 2007-11-18 19:02:55 UTC (rev
4376)
+++ trunk/matplotlib/lib/matplotlib/image.py 2007-11-18 19:06:49 UTC (rev
4377)
@@ -410,9 +410,107 @@
raise RuntimeError('Cannot change colors after loading data')
cm.ScalarMappable.set_cmap(self, norm)
+class PcolorImage(martist.Artist, cm.ScalarMappable):
+ def __init__(self, ax,
+ x=None,
+ y=None,
+ A=None,
+ cmap = None,
+ norm = None,
+ **kwargs
+ ):
+ """
+ cmap defaults to its rc setting
+ cmap is a colors.Colormap instance
+ norm is a colors.Normalize instance to map luminance to 0-1
+ Additional kwargs are matplotlib.artist properties
+ """
+ martist.Artist.__init__(self)
+ cm.ScalarMappable.__init__(self, norm, cmap)
+ self.axes = ax
+ self._rgbacache = None
+ self.update(kwargs)
+ self.set_data(x, y, A)
+
+ def make_image(self, magnification=1.0):
+ if self._A is None:
+ raise RuntimeError('You must first set the image array')
+ fc = self.axes.get_frame().get_facecolor()
+ bg = mcolors.colorConverter.to_rgba(fc, 0)
+ bg = (npy.array(bg)*255).astype(npy.uint8)
+ x0, y0, v_width, v_height = self.axes.viewLim.get_bounds()
+ l, b, width, height = self.axes.bbox.get_bounds()
+ width *= magnification
+ height *= magnification
+ if self.check_update('array'):
+ A = self.to_rgba(self._A, alpha=self._alpha, bytes=True)
+ self._rgbacache = A
+ if self._A.ndim == 2:
+ self.is_grayscale = self.cmap.is_gray()
+ else:
+ A = self._rgbacache
+ im = _image.pcolor2(self._Ax, self._Ay, A,
+ height, width,
+ (x0, x0+v_width, y0, y0+v_height),
+ bg)
+ im.is_grayscale = self.is_grayscale
+ return im
+
+ def draw(self, renderer, *args, **kwargs):
+ if not self.get_visible(): return
+ im = self.make_image(renderer.get_image_magnification())
+ l, b, widthDisplay, heightDisplay = self.axes.bbox.get_bounds()
+ renderer.draw_image(l, b, im, self.axes.bbox)
+
+
+ def set_data(self, x, y, A):
+ A = ma.asarray(A)
+ if x is None:
+ x = npy.arange(0, A.shape[1]+1, dtype=npy.float64)
+ else:
+ x = npy.asarray(x, npy.float64).ravel()
+ if y is None:
+ y = npy.arange(0, A.shape[0]+1, dtype=npy.float64)
+ else:
+ y = npy.asarray(y, npy.float64).ravel()
+
+ if A.shape[:2] != (y.size-1, x.size-1):
+ print A.shape
+ print y.size
+ print x.size
+ raise ValueError("Axes don't match array shape")
+ if A.ndim not in [2, 3]:
+ raise ValueError("A must be 2D or 3D")
+ if A.ndim == 3 and A.shape[2] == 1:
+ A.shape = A.shape[:2]
+ self.is_grayscale = False
+ if A.ndim == 3:
+ if A.shape[2] in [3, 4]:
+ if (A[:,:,0] == A[:,:,1]).all() and (A[:,:,0] ==
A[:,:,2]).all():
+ self.is_grayscale = True
+ else:
+ raise ValueError("3D arrays must have RGB or RGBA as last dim")
+ self._A = A
+ self._Ax = x
+ self._Ay = y
+ self.update_dict['array'] = True
+
+ def set_array(self, *args):
+ raise NotImplementedError('Method not supported')
+
+ def set_alpha(self, alpha):
+ """
+ Set the alpha value used for blending - not supported on
+ all backends
+
+ ACCEPTS: float
+ """
+ martist.Artist.set_alpha(self, alpha)
+ self.update_dict['array'] = True
+
class FigureImage(martist.Artist, cm.ScalarMappable):
def __init__(self, fig,
cmap = None,
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: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins