Revision: 7309
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7309&view=rev
Author: efiring
Date: 2009-07-30 19:32:15 +0000 (Thu, 30 Jul 2009)
Log Message:
-----------
User-generated colormaps are handled more easily.
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/doc/api/api_changes.rst
trunk/matplotlib/examples/pylab_examples/custom_cmap.py
trunk/matplotlib/lib/matplotlib/cm.py
trunk/matplotlib/lib/matplotlib/image.py
trunk/matplotlib/lib/matplotlib/pyplot.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-07-30 17:08:23 UTC (rev 7308)
+++ trunk/matplotlib/CHANGELOG 2009-07-30 19:32:15 UTC (rev 7309)
@@ -1,3 +1,7 @@
+2009-07-30 Add set_cmap and register_cmap, and improve get_cmap,
+ to provide convenient handling of user-generated
+ colormaps. - EF
+
2009-07-28 Quiver speed improved, thanks to tip by Ray Speth. -EF
2009-07-27 Simplify argument handling code for plot method. -EF
Modified: trunk/matplotlib/doc/api/api_changes.rst
===================================================================
--- trunk/matplotlib/doc/api/api_changes.rst 2009-07-30 17:08:23 UTC (rev
7308)
+++ trunk/matplotlib/doc/api/api_changes.rst 2009-07-30 19:32:15 UTC (rev
7309)
@@ -21,6 +21,11 @@
Changes beyond 0.98.x
=====================
+* User-generated colormaps can now be added to the set recognized
+ by :func:`matplotlib.cm.get_cmap`. Colormaps can be made the
+ default and applied to the current image using
+ :func:`matplotlib.pyplot.set_cmap`.
+
* changed use_mrecords default to False in mlab.csv2rec since this is
partially broken
Modified: trunk/matplotlib/examples/pylab_examples/custom_cmap.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/custom_cmap.py 2009-07-30
17:08:23 UTC (rev 7308)
+++ trunk/matplotlib/examples/pylab_examples/custom_cmap.py 2009-07-30
19:32:15 UTC (rev 7309)
@@ -103,11 +103,25 @@
(1.0, 0.0, 0.0))
}
+# Now we will use this example to illustrate 3 ways of
+# handling custom colormaps.
+# First, the most direct and explicit:
blue_red1 = LinearSegmentedColormap('BlueRed1', cdict1)
+
+# Second, create the map explicitly and register it.
+# Like the first method, this method works with any kind
+# of Colormap, not just
+# a LinearSegmentedColormap:
+
blue_red2 = LinearSegmentedColormap('BlueRed2', cdict2)
-blue_red3 = LinearSegmentedColormap('BlueRed3', cdict3)
+plt.register_cmap(cmap=blue_red2)
+# Third, for LinearSegmentedColormap only,
+# leave everything to register_cmap:
+
+plt.register_cmap(name='BlueRed3', data=cdict3) # optional lut kwarg
+
x = np.arange(0, np.pi, 0.1)
y = np.arange(0, 2*np.pi, 0.1)
X, Y = np.meshgrid(x,y)
@@ -121,13 +135,33 @@
plt.colorbar()
plt.subplot(1,3,2)
-plt.imshow(Z, interpolation='nearest', cmap=blue_red2)
+cmap = plt.get_cmap('BlueRed2')
+plt.imshow(Z, interpolation='nearest', cmap=cmap)
plt.colorbar()
+# Now we will set the third cmap as the default. One would
+# not normally do this in the middle of a script like this;
+# it is done here just to illustrate the method.
+
+plt.rcParams['image.cmap'] = 'BlueRed3'
+
+# Also see below for an alternative, particularly for
+# interactive use.
+
plt.subplot(1,3,3)
-plt.imshow(Z, interpolation='nearest', cmap=blue_red3)
+plt.imshow(Z, interpolation='nearest')
plt.colorbar()
+# Or as yet another variation, we could replace the rcParams
+# specification *before* the imshow with the following *after*
+# imshow:
+#
+# plt.set_cmap('BlueRed3')
+#
+# This sets the new default *and* sets the colormap of the last
+# image-like item plotted via pyplot, if any.
+
+
plt.suptitle('Custom Blue-Red colormaps')
plt.show()
Modified: trunk/matplotlib/lib/matplotlib/cm.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/cm.py 2009-07-30 17:08:23 UTC (rev
7308)
+++ trunk/matplotlib/lib/matplotlib/cm.py 2009-07-30 19:32:15 UTC (rev
7309)
@@ -9,16 +9,79 @@
import matplotlib.cbook as cbook
from matplotlib._cm import *
+# Dictionary for user-registered colormaps:
+cmap_d = dict()
+# Using this second dictionary allows us to handle any
+# Colormap instance; the built-in datad is only for
+# LinearSegmentedColormaps. The advantage of keeping
+# datad is that it delays the generation of the Colormap
+# instance until it is actually needed. Generating the
+# instance is fast enough, and typically done few enough
+# times, that there is no need to cache the result.
+def register_cmap(name=None, cmap=None, data=None, lut=None):
+ """
+ Add a colormap to the set recognized by :func:`get_cmap`.
+
+ It can be used in two ways::
+
+ register_cmap(name='swirly', cmap=swirly_cmap)
+
+ register_cmap(name='choppy', data=choppydata, lut=128)
+
+ In the first case, *cmap* must be a :class:`colors.Colormap`
+ instance. The *name* is optional; if absent, the name will
+ be the :attr:`name` attribute of the *cmap*.
+
+ In the second case, the three arguments are passed to
+ the :class:`colors.LinearSegmentedColormap` initializer,
+ and the resulting colormap is registered.
+
+ """
+ if name is None:
+ try:
+ name = cmap.name
+ except AttributeError:
+ raise ValueError("Arguments must include a name or a Colormap")
+
+ if not cbook.is_string_like(name):
+ raise ValueError("Colormap name must be a string")
+
+ if isinstance(cmap, colors.Colormap):
+ cmap_d[name] = cmap
+ return
+
+ # For the remainder, let exceptions propagate.
+ if lut is None:
+ lut = mpl.rcParams['image.lut']
+ cmap = colors.LinearSegmentedColormap(name, data, lut)
+ cmap_d[name] = cmap
+
def get_cmap(name=None, lut=None):
"""
- Get a colormap instance, defaulting to rc values if *name* is None
+ Get a colormap instance, defaulting to rc values if *name* is None.
+
+ Colormaps added with :func:`register_cmap` take precedence over
+ builtin colormaps.
+
+ If *name* is a :class:`colors.Colormap` instance, it will be
+ returned.
"""
- if name is None: name = mpl.rcParams['image.cmap']
- if lut is None: lut = mpl.rcParams['image.lut']
+ if name is None:
+ name = mpl.rcParams['image.cmap']
- assert(name in datad.keys())
+ if isinstance(name, colors.Colormap):
+ return name
+
+ if name in cmap_d:
+ return cmap_d[name]
+
+ if name not in datad:
+ raise ValueError("%s is not a known colormap name" % name)
+
+ if lut is None:
+ lut = mpl.rcParams['image.lut']
return colors.LinearSegmentedColormap(name, datad[name], lut)
class ScalarMappable:
@@ -116,9 +179,9 @@
"""
set the colormap for luminance data
- ACCEPTS: a colormap
+ ACCEPTS: a colormap or registered colormap name
"""
- if cmap is None: cmap = get_cmap()
+ cmap = get_cmap(cmap)
self.cmap = cmap
self.changed()
Modified: trunk/matplotlib/lib/matplotlib/image.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/image.py 2009-07-30 17:08:23 UTC (rev
7308)
+++ trunk/matplotlib/lib/matplotlib/image.py 2009-07-30 19:32:15 UTC (rev
7309)
@@ -512,7 +512,7 @@
def set_cmap(self, cmap):
if self._A is not None:
raise RuntimeError('Cannot change colors after loading data')
- cm.ScalarMappable.set_cmap(self, norm)
+ cm.ScalarMappable.set_cmap(self, cmap)
class PcolorImage(martist.Artist, cm.ScalarMappable):
'''
Modified: trunk/matplotlib/lib/matplotlib/pyplot.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/pyplot.py 2009-07-30 17:08:23 UTC (rev
7308)
+++ trunk/matplotlib/lib/matplotlib/pyplot.py 2009-07-30 19:32:15 UTC (rev
7309)
@@ -17,7 +17,7 @@
from matplotlib.scale import get_scale_docs, get_scale_names
from matplotlib import cm
-from matplotlib.cm import get_cmap
+from matplotlib.cm import get_cmap, register_cmap
import numpy as np
@@ -1396,8 +1396,26 @@
im.set_clim(vmin, vmax)
draw_if_interactive()
+def set_cmap(cmap):
+ '''
+ set the default colormap to *cmap* and apply to current image if any.
+ See help(colormaps) for more information.
+ *cmap* must be a :class:`colors.Colormap` instance, or
+ the name of a registered colormap.
+ See :func:`register_cmap` and :func:`get_cmap`.
+ '''
+ cmap = cm.get_cmap(cmap)
+
+ rc('image', cmap=cmap.name)
+ im = gci()
+
+ if im is not None:
+ im.set_cmap(cmap)
+ draw_if_interactive()
+
+
def imread(*args, **kwargs):
return _imread(*args, **kwargs)
if _imread.__doc__ is not None:
@@ -6327,12 +6345,12 @@
*bbox_to_anchor* keyword argument. bbox_to_anchor can be an instance
of BboxBase(or its derivatives) or a tuple of 2 or 4 floats.
For example, ::
-
+
loc = 'upper right', bbox_to_anchor = (0.5, 0.5)
will place the legend so that the upper right corner of the legend at
the center of the axes.
-
+
The legend location can be specified in other coordinate, by using the
*bbox_transform* keyword.
@@ -6365,7 +6383,7 @@
*fancybox*: [ None | False | True ]
if True, draw a frame with a round fancybox. If None, use rc
-
+
*shadow*: [ None | False | True ]
If *True*, draw a shadow behind legend. If *None*, use rc settings.
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins