On 06/03/2010 10:43 AM, Jim Vickroy wrote: > Eric Firing wrote: >> On 06/03/2010 10:00 AM, Jim Vickroy wrote: >> >>> I want to generate a 2-d figure with a (fixed) color scale that does >>> not vary with the range of the data being plotted. >>> >>> How do I do this? Attempts to specify vimin and vmax appear to be ignored. >>> >>> The following example: >>> >>> #<code> >>> import numpy >>> data = numpy.zeros(shape=(240,240),dtype=int) >>> data[ 0: 80] = -1 >>> data[ 80:160] = 0 >>> data[160:] = 1 >>> >>> import matplotlib.pyplot as plot >>> figure = plot.figure() >>> ax = figure.add_subplot(111) >>> cax = ax.imshow(data, interpolation='bilinear') >>> ax.set_title('test data with fixed colorbar') >>> >> >> Adding to what JJ said, note that setting the ticks on the colorbar has >> no effect on the norm used in color mapping. The vmin and vmax kwargs >> to imshow get passed to the norm, so they do set the mapping range. >> >> >>> colorbar = figure.colorbar(cax, ticks=[-1, 0, 1]) >>> colorbar.ax.set_yticklabels(['-1', '0', '1']) >>> >> >> Please avoid setting the ticklabels directly--it is almost always >> unnecessary, and it is too easy to shoot yourself in the foot. If the >> default tick label formatting is inadequate, you can use the format >> kwarg in colorbar. >> >> From the docstring: >> >> *ticks* [ None | list of ticks | Locator object ] >> If None, ticks are determined automatically from the >> input. >> *format* [ None | format string | Formatter object ] >> If None, the >> :class:`~matplotlib.ticker.ScalarFormatter` is used. >> If a format string is given, e.g. '%.3f', that is >> used. An alternative >> :class:`~matplotlib.ticker.Formatter` object may be >> given instead. >> >> >> Eric >> > > Thanks for this advice. > > In my case, the data being plotted is in the range 0-255, but the > color-bar labels are to be in the range 1-4095. So I have the following > code snippet: > > colorbar = figure.colorbar(image, cax, orientation='vertical', ticks=(0, > 64, 128, 192, 254)) > colorbar.ax.set_yticklabels(('1','8','64','512','4095')) # colorbar > labels (which are to be in units of DN/sec on a log10 scale) > > Is there a better way to do this?
The advantage of using a custom formatter is that it formats actual tick values, so if you decide to use a different set of tick locations, you don't have to remember to change the labels. A formatter for a complicated case such as the above could use a dictionary, which would at least generate a KeyError if you changed a tick without adding the new location to the dictionary, or, better, it could calculate the label numbers. Suppose you have a function to do the translation: def to_DNpersec(x): dn = ... whatever function of x return dn import matplotlib as mpl class DNpersecFormatter(mpl.ticker.Formatter): def __call__(self, val, pos=None): dn = to_DNpersec(val) return "%d" % round(dn) ... colorbar = figure.colorbar(image, cax, orientation='vertical', ticks=(0, 64, 128, 192, 254), format=DNpersecFormatter()) Eric > > -- jv > > >> >> >>> plot.show() >>> #</code> >>> >>> produces a figure with 3 color bands (blue,green,red) and matching color >>> bar with labels (-1,0,1) as expected. >>> >>> if the data[160:]=1 specification is deleted, in the above code, the >>> resulting figure has 2 color bands (blue,red) and the associated color >>> bar is identical to the original, but the labels are (-1,0). >>> >>> What I want, in this second case, is a blue-green figure and a color bar >>> with labels identical to the original example. >>> >>> -- jv ------------------------------------------------------------------------------ ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users