Revision: 4934
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4934&view=rev
Author: efiring
Date: 2008-02-03 13:26:42 -0800 (Sun, 03 Feb 2008)
Log Message:
-----------
Modified BoundaryNorm, examples, colorbar support
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/examples/colorbar_only.py
trunk/matplotlib/examples/image_masked.py
trunk/matplotlib/lib/matplotlib/colorbar.py
trunk/matplotlib/lib/matplotlib/colors.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-02-03 21:10:22 UTC (rev 4933)
+++ trunk/matplotlib/CHANGELOG 2008-02-03 21:26:42 UTC (rev 4934)
@@ -1,3 +1,6 @@
+2008-02-03 Added BoundaryNorm, with examples in colorbar_only.py
+ and image_masked.py. - EF
+
2008-02-03 Force dpi=72 in pdf backend to fix picture size bug. - JKS
2008-02-01 Fix reference leak in ft2font Glyph objects. - MGD
Modified: trunk/matplotlib/examples/colorbar_only.py
===================================================================
--- trunk/matplotlib/examples/colorbar_only.py 2008-02-03 21:10:22 UTC (rev
4933)
+++ trunk/matplotlib/examples/colorbar_only.py 2008-02-03 21:26:42 UTC (rev
4934)
@@ -35,7 +35,7 @@
# 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)
+norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
cb2 = mpl.colorbar.ColorbarBase(ax2, cmap=cmap,
norm=norm,
# to use 'extend', you must
Modified: trunk/matplotlib/examples/image_masked.py
===================================================================
--- trunk/matplotlib/examples/image_masked.py 2008-02-03 21:10:22 UTC (rev
4933)
+++ trunk/matplotlib/examples/image_masked.py 2008-02-03 21:26:42 UTC (rev
4934)
@@ -1,6 +1,8 @@
#!/usr/bin/env python
'''imshow with masked array input and out-of-range colors.
+ The second subplot illustrates the use of BoundaryNorm to
+ get a filled contour effect.
'''
from pylab import *
@@ -31,10 +33,23 @@
# range to which the regular palette color scale is applied.
# Anything above that range is colored based on palette.set_over, etc.
+subplot(1,2,1)
im = imshow(Zm, interpolation='bilinear',
cmap=palette,
norm = colors.Normalize(vmin = -1.0, vmax = 1.0, clip = False),
origin='lower', extent=[-3,3,-3,3])
title('Green=low, Red=high, Blue=bad')
-colorbar(im, extend='both', shrink=0.8)
+colorbar(im, extend='both', orientation='horizontal', shrink=0.8)
+
+subplot(1,2,2)
+im = imshow(Zm, interpolation='nearest',
+ cmap=palette,
+ norm = colors.BoundaryNorm([-1, -0.5, -0.2, 0, 0.2, 0.5, 1],
+ ncolors=256, clip = False),
+ origin='lower', extent=[-3,3,-3,3])
+title('With BoundaryNorm')
+colorbar(im, extend='both', spacing='proportional',
+ orientation='horizontal', shrink=0.8)
+
show()
+
Modified: trunk/matplotlib/lib/matplotlib/colorbar.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/colorbar.py 2008-02-03 21:10:22 UTC (rev
4933)
+++ trunk/matplotlib/lib/matplotlib/colorbar.py 2008-02-03 21:26:42 UTC (rev
4934)
@@ -323,6 +323,9 @@
nv = len(self._values)
base = 1 + int(nv/10)
locator = ticker.IndexLocator(base=base, offset=0)
+ elif isinstance(self.norm, colors.BoundaryNorm):
+ b = self.norm.boundaries
+ locator = ticker.FixedLocator(b, nbins=10)
elif isinstance(self.norm, colors.LogNorm):
locator = ticker.LogLocator()
else:
@@ -389,6 +392,23 @@
self._boundaries = b
self._values = v
return
+ elif isinstance(self.norm, colors.BoundaryNorm):
+ b = list(self.norm.boundaries)
+ if self.extend in ('both', 'min'):
+ b = [b[0]-1] + b
+ if self.extend in ('both', 'max'):
+ b = b + [b[-1] + 1]
+ b = npy.array(b)
+ v = npy.zeros((len(b)-1,), dtype=float)
+ bi = self.norm.boundaries
+ v[self._inside] = 0.5*(bi[:-1] + bi[1:])
+ if self.extend in ('both', 'min'):
+ v[0] = b[0] - 1
+ if self.extend in ('both', 'max'):
+ v[-1] = b[-1] + 1
+ self._boundaries = b
+ self._values = v
+ return
else:
if not self.norm.scaled():
self.norm.vmin = 0
Modified: trunk/matplotlib/lib/matplotlib/colors.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/colors.py 2008-02-03 21:10:22 UTC (rev
4933)
+++ trunk/matplotlib/lib/matplotlib/colors.py 2008-02-03 21:26:42 UTC (rev
4934)
@@ -685,13 +685,41 @@
return vmin * pow((vmax/vmin), value)
class BoundaryNorm(Normalize):
- def __init__(self, boundaries, clip=False):
+ '''
+ Generate a colormap index based on discrete intervals.
+
+ Unlike Normalize or LogNorm, BoundaryNorm maps values
+ to integers instead of to the interval 0-1.
+
+ Mapping to the 0-1 interval could have been done via
+ piece-wise linear interpolation, but using integers seems
+ simpler, and reduces the number of conversions back and forth
+ between integer and floating point.
+ '''
+ def __init__(self, boundaries, ncolors, clip=False):
+ '''
+ args:
+ boundaries: a monotonically increasing sequence
+ ncolors: number of colors in the colormap to be used
+
+ If b[i] <= v < b[i+1] then v is mapped to color j;
+ as i varies from 0 to len(boundaries)-2,
+ j goes from 0 to ncolors-1.
+
+ Out-of-range values are mapped to -1 if low and ncolors
+ if high; these are converted to valid indices by
+ Colormap.__call__.
+ '''
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)
+ self.Ncmap = ncolors
+ if self.N-1 == self.Ncmap:
+ self._interp = False
+ else:
+ self._interp = True
def __call__(self, x, clip=None):
if clip is None:
@@ -704,15 +732,17 @@
iret = npy.zeros(x.shape, dtype=npy.int16)
for i, b in enumerate(self.boundaries):
iret[xx>=b] = i
+ if self._interp:
+ iret = (iret * (float(self.Ncmap-1)/(self.N-2))).astype(npy.int16)
iret[xx<self.vmin] = -1
- iret[xx>=self.vmax] = self.N
- ret = ma.array(iret / float(self.N-1), mask=mask)
+ iret[xx>=self.vmax] = self.Ncmap
+ ret = ma.array(iret, mask=mask)
if ret.shape == () and not mask:
- ret = float(ret) # assume python scalar
+ ret = int(ret) # assume python scalar
return ret
def inverse(self, value):
- return self.midpoints[int(value*(self.N-1))]
+ return ValueError("BoundaryNorm is not invertible")
class NoNorm(Normalize):
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