Revision: 4930
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4930&view=rev
Author: efiring
Date: 2008-02-01 23:53:03 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
Added BoundaryNorm to support irregular discrete color intervals
Modified Paths:
--------------
trunk/matplotlib/examples/colorbar_only.py
trunk/matplotlib/lib/matplotlib/colorbar.py
trunk/matplotlib/lib/matplotlib/colors.py
Modified: trunk/matplotlib/examples/colorbar_only.py
===================================================================
--- trunk/matplotlib/examples/colorbar_only.py 2008-02-01 20:15:59 UTC (rev
4929)
+++ trunk/matplotlib/examples/colorbar_only.py 2008-02-02 07:53:03 UTC (rev
4930)
@@ -2,12 +2,12 @@
Make a colorbar as a separate figure.
'''
-import pylab
-import matplotlib as mpl
+from matplotlib import pyplot, mpl
# Make a figure and axes with dimensions as desired.
-fig = pylab.figure(figsize=(8,1.5))
-ax = fig.add_axes([0.05, 0.4, 0.9, 0.5])
+fig = pyplot.figure(figsize=(8,3))
+ax1 = fig.add_axes([0.05, 0.65, 0.9, 0.15])
+ax2 = fig.add_axes([0.05, 0.25, 0.9, 0.15])
# Set the colormap and norm to correspond to the data for which
# the colorbar will be used.
@@ -19,10 +19,33 @@
# standalone colorbar. There are many more kwargs, but the
# following gives a basic continuous colorbar with ticks
# and labels.
-cb = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
+cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cmap,
norm=norm,
orientation='horizontal')
-cb.set_label('Some Units')
+cb1.set_label('Some Units')
-pylab.show()
+# The second example illustrates the use of a ListedColormap, a
+# BoundaryNorm, and extended ends to show the "over" and "under"
+# value colors.
+cmap = mpl.colors.ListedColormap(['r', 'g', 'b', 'c'])
+cmap.set_over('0.25')
+cmap.set_under('0.75')
+# If a ListedColormap is used, the length of the bounds array must be
+# one greater than the length of the color list. The bounds must be
+# monotonically increasing.
+bounds = [1, 2, 4, 7, 8]
+norm = mpl.colors.BoundaryNorm(bounds)
+cb2 = mpl.colorbar.ColorbarBase(ax2, cmap=cmap,
+ norm=norm,
+ # to use 'extend', you must
+ # specify two extra boundaries:
+ boundaries=[0]+bounds+[13],
+ extend='both',
+ ticks=bounds, # optional
+ spacing='proportional',
+ orientation='horizontal')
+cb2.set_label('Discrete intervals, some other units')
+
+pyplot.show()
+
Modified: trunk/matplotlib/lib/matplotlib/colorbar.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/colorbar.py 2008-02-01 20:15:59 UTC (rev
4929)
+++ trunk/matplotlib/lib/matplotlib/colorbar.py 2008-02-02 07:53:03 UTC (rev
4930)
@@ -356,7 +356,7 @@
if b is None:
b = self.boundaries
if b is not None:
- self._boundaries = npy.array(b)
+ self._boundaries = npy.asarray(b, dtype=float)
if self.values is None:
self._values = 0.5*(self._boundaries[:-1]
+ self._boundaries[1:])
@@ -456,7 +456,12 @@
Return colorbar data coordinates for the boundaries of
a proportional colorbar.
'''
- y = self.norm(self._boundaries.copy())
+ if isinstance(self.norm, colors.BoundaryNorm):
+ b = self._boundaries[self._inside]
+ y = (self._boundaries - self._boundaries[0])
+ y = y / (self._boundaries[-1] - self._boundaries[0])
+ else:
+ y = self.norm(self._boundaries.copy())
if self.extend in ('both', 'min'):
y[0] = -0.05
if self.extend in ('both', 'max'):
@@ -492,7 +497,7 @@
within range, together with their corresponding colorbar
data coordinates.
'''
- if isinstance(self.norm, colors.NoNorm):
+ if isinstance(self.norm, (colors.NoNorm, colors.BoundaryNorm)):
b = self._boundaries
xn = x
xout = x
Modified: trunk/matplotlib/lib/matplotlib/colors.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/colors.py 2008-02-01 20:15:59 UTC (rev
4929)
+++ trunk/matplotlib/lib/matplotlib/colors.py 2008-02-02 07:53:03 UTC (rev
4930)
@@ -684,7 +684,37 @@
else:
return vmin * pow((vmax/vmin), value)
+class BoundaryNorm(Normalize):
+ def __init__(self, boundaries, clip=False):
+ self.clip = clip
+ self.vmin = boundaries[0]
+ self.vmax = boundaries[-1]
+ self.boundaries = npy.asarray(boundaries)
+ self.midpoints = 0.5 *(self.boundaries[:-1] + self.boundaries[1:])
+ self.N = len(self.boundaries)
+ def __call__(self, x, clip=None):
+ if clip is None:
+ clip = self.clip
+ x = ma.asarray(x)
+ mask = ma.getmaskarray(x)
+ xx = x.filled(self.vmax+1)
+ if clip:
+ npy.clip(xx, self.vmin, self.vmax)
+ iret = npy.zeros(x.shape, dtype=npy.int16)
+ for i, b in enumerate(self.boundaries):
+ iret[xx>=b] = i
+ iret[xx<self.vmin] = -1
+ iret[xx>=self.vmax] = self.N
+ ret = ma.array(iret / float(self.N-1), mask=mask)
+ if ret.shape == () and not mask:
+ ret = float(ret) # assume python scalar
+ return ret
+
+ def inverse(self, value):
+ return self.midpoints[int(value*(self.N-1))]
+
+
class NoNorm(Normalize):
'''
Dummy replacement for Normalize, for the case where we
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 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins