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

Reply via email to