Screenshot instructions:
Windows
Mac
Red Hat Linux
Ubuntu
Click URL instructions:
Rightclick on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)
From: Michael Rawlins <rawlins02@ya...>  20110105 16:44:23

How does one define a range of colors for a custom userdefined colormap? I'm fairly new to matplotlib and have been using standard colormaps. Below is a sample program that makes a color bar based on the hot colormap. I'd like to have a colormap like hot, but that starts at, say, orange (near 14%), and runs to black (40%). ''' Make a colorbar as a separate figure. ''' from matplotlib import pyplot, mpl import sys,getopt from mpl_toolkits.basemap import Basemap, shiftgrid, cm #from netCDF3 import Dataset as NetCDFFile from mpl_toolkits.basemap import NetCDFFile from pylab import * usemaprev=True # Make a figure and axes with dimensions as desired. fig = pyplot.figure(figsize=(8,3)) ax1 = fig.add_axes([0.05, 0.4, 0.9, 0.14]) # Set the colormap and norm to correspond to the data for which # the colorbar will be used. cmap = mpl.cm.cool norm = mpl.colors.Normalize(vmin=0, vmax=40) # here set colorbar min/max # alter a matplotlib color table, # cm.jet is very useful scheme, but reversed colors are better for drought colordict=cm.jet._segmentdata.copy() # dictionary ('blue', 'green', 'red') of nested tuples # autumn scheme is yellow to red colordict=cm.hot._segmentdata.copy() #mycolormap=cm.jet mycolormap=cm.hot for k in colordict.keys(): colordict[k]=[list(q) for q in colordict[k]] #convert nested tuples to nested list for a in colordict[k]: a[0]=1.a[0] #in inner list, change normalized value to 1  value. colordict[k].reverse() #reverse order of outer list maprev = cm.colors.LinearSegmentedColormap("maprev", colordict) #map = cm.colors.LinearSegmentedColormap("map", colordict) if usemaprev: mycolormap=maprev print "using reverse of defined colormap" #ax1 = fig.add_axes([0.05, 0.65, 0.9, 0.15]) #cax = axes([0.85, 0.1, 0.05, 0.7]) # setup colorbar axes #colorbar(format='%d') # draw colorbar # ColorbarBase derives from ScalarMappable and puts a colorbar # in a specified axes, so it has everything needed for a # standalone colorbar. There are many more kwargs, but the # following gives a basic continuous colorbar with ticks # and labels. #cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=jetrev, # norm=norm, # orientation='horizontal') cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=mycolormap, norm=norm, orientation='horizontal') cb1.set_label('percent') #pyplot.show() plt.savefig('colormap.png') 
From: Paul Ivanov <pivanov314@gm...>  20110105 21:10:06
Attachments:
Message as HTML

Michael Rawlins, on 20110105 08:44, wrote: > How does one define a range of colors for a custom userdefined > colormap? I'm fairly new to matplotlib and have been using > standard colormaps. Below is a sample program that makes a > color bar based on the hot colormap. I'd like to have a > colormap like hot, but that starts at, say, orange (near 14%), > and runs to black (40%). Hi Michael, first a quick aside: your reversing of the colormap is unnecessary  just change the colordict assignment line to be: colordict=cm.hot_r._segmentdata.copy() and get rid of the two nested for loops. Or better still, get rid of colordict altogether and just use maprev = cm.hot_r Ok, as far as your question  I'm not certain that this is what you're asking for  but if you want to construct a colormap that "stretches" the portion of your plot that goes from 14 to 40 "percent" (as labeled), to be the entire range of a colormap  use the following: All colormaps take as input a value from 0.01.0, and give you back an rgba tuple. You already have a normalization 'norm' in there which maps an arbitrary interval (040 in your case) to the 0.01.0 interval. So you like the color value at 14  let's find out what the scalar value for 14 is, once it's mapped to the 0.01.0 interval. In [68]: norm(14) Out[68]: 0.34999999999999998 So that's the value we will pass to cm.hot_r to get the color at 14. Let's verify that this is actually what's going on  I'll create a new figure and plot just one big dot on there of what should hopefully be the same color. In [69]: f, ax = plt.subplots(1,1) In [70]: plt.scatter(0,0,c=cm.hot_r(norm(14)),s=1000) # c is color, s is size Out[70]: <matplotlib.collections.CircleCollection object at 0xae9002c> Ok, that looks good. We can repeat the procedure for the 40 "percent" case In [89]: norm(40) Out[89]: 1.0 In [90]: plt.scatter(0,0,c=cm.hot_r(norm(40)),s=1000) Out[90]: <matplotlib.collections.CircleCollection object at 0xae97c4c> No surprises there (it's black). Now let's create our own segmented map. You can look at the documentation and an example: http://matplotlib.sourceforge.net/api/colors_api.html#matplotlib.colors.LinearSegmentedColormap http://matplotlib.sourceforge.net/examples/pylab_examples/custom_cmap.html but a LinearSegmentedColormap just splits deals with the rgb channels seperately, and for each color, defines transition points in the 0.01.0 interval which are refered to as 'x' in the links above, as well as the color to use before the transition point ('y0'), and the color to use after the point ('y1'). Here's a quote from the docs about this: Each row in the table for a given color is a sequence of x, y0, y1 tuples. In each sequence, x must increase monotonically from 0 to 1. For any input value z falling between x[i] and x[i+1], the output value of a given color will be linearly interpolated between y1[i] and y0[i+1]: row i: x y0 y1 / / row i+1: x y0 y1 Hence y0 in the first row and y1 in the last row are never used. Armed with this knowledge, you can now use the color from cm.hot_r(norm(14)) to get the entries for the first rows of your new map (remember that you're doing red, green, and blue seperately)  and then remap the remaining transition points (the 'x' portion of the tuple) to stretch portion of the colormap's 0.01.0 interval that you're interested in (i.e. map 0.3451.0 to 0.01.0). Now that's only if you want full control of the linear segments  there's a quick and dirty way to get what you want by specifying a ListedColormap using values taken from the colormap you're using. I'll just get a whole bunch of values from the desired interval of the colormap, map them through the colormap, and get my new colormap out. In [209]: vals = norm(np.linspace(14,40,1000)) In [210]: newcm = cm.colors.ListedColormap(cm.hot_r(vals)) Let's plot the original map (as in your email), and the new one we created. In [211]: f,(ax2,ax3) = plt.subplots(2,1) In [212]: cb2 = mpl.colorbar.ColorbarBase(ax2, cmap=cm.hot_r, .....: norm=norm, .....: orientation='horizontal') In [213]: cb2.set_label('"percent"') In [214]: In [215]: cb3 = mpl.colorbar.ColorbarBase(ax3, cmap=newcm, .....: orientation='horizontal') In [216]: cb3.set_label("colormap interval 0.01.0") In [217]: plt.draw() And to further clarify that we did the right thing, let's adjust the xlim on that original plot. In [221]: ax2.set_xlim(norm(14),norm(40)) Out[221]: (0.34999999999999998, 1.0) In [222]: plt.draw() Hope this clears things up,  Paul Ivanov 314 address only used for lists, offlist direct email at: http://pirsquared.org  GPG/PGP key id: 0x0F3E28F7 
From: Michael Rawlins <rawlins02@ya...>  20110105 22:42:17

Paul, Thanks for the detailed tutorial. I'm getting errors when I attempt to use plt.subplots(1,1) and the newcm assignment. Traceback (most recent call last): File "colorbar_Mytest2.py", line 17, in <module> f, ax = plt.subplots(1,1) AttributeError: 'module' object has no attribute 'subplots' Here are just a few of the errors I'm getting when executing colorbar command with newcm. Also, what does In and Out do, as in Out[68]: 0.34999999999999998 ? plt.draw() File "/usr/lib/pymodules/python2.6/matplotlib/pyplot.py", line 352, in draw get_current_fig_manager().canvas.draw() File "/usr/lib/pymodules/python2.6/matplotlib/backends/backend_tkagg.py", line 215, in draw FigureCanvasAgg.draw(self) File "/usr/lib/pymodules/python2.6/matplotlib/backends/backend_agg.py", line 314, in draw self.figure.draw(self.renderer) File "/usr/lib/pymodules/python2.6/matplotlib/artist.py", line 46, in draw_wrapper draw(artist, renderer, *kl) File "/usr/lib/pymodules/python2.6/matplotlib/figure.py", line 773, in draw for a in self.axes: a.draw(renderer) File "/usr/lib/pymodules/python2.6/matplotlib/artist.py", line 46, in draw_wrapper Here's a simplified version that works for me: from matplotlib import pyplot, mpl import sys,getopt from mpl_toolkits.basemap import Basemap, shiftgrid, cm #from netCDF3 import Dataset as NetCDFFile from mpl_toolkits.basemap import NetCDFFile from pylab import * vals = norm(np.linspace(14,40,1000)) newcm = cm.colors.ListedColormap(cm.hot_r(vals)) # Make a figure and axes with dimensions as desired. fig = pyplot.figure(figsize=(8,3)) #f, ax = plt.subplots(1,1) ax1 = fig.add_axes([0.05, 0.4, 0.9, 0.14]) #ax2 = fig.add_axes([0.05, 0.8, 0.9, 0.6]) # Set the colormap and norm to correspond to the data for which # the colorbar will be used. cmap = mpl.cm.cool norm = mpl.colors.Normalize(vmin=0, vmax=40) # here set colorbar min/max mycolormap=cm.hot maprev = cm.hot_r #f,(ax2,ax3) = plt.subplots(2,1) cb2 = mpl.colorbar.ColorbarBase(ax1, cmap=cm.hot_r, norm=norm, orientation='horizontal') #cb2.set_label('"percent"') #cb3 = mpl.colorbar.ColorbarBase(ax1, cmap=newcm, # orientation='horizontal') #cb3.set_label("colormap interval 0.01.0") plt.draw() 
From: Paul Ivanov <pivanov314@gm...>  20110106 00:15:13
Attachments:
Message as HTML

Michael Rawlins, on 20110105 14:42, wrote: > Thanks for the detailed tutorial. I'm getting errors when I > attempt to use plt.subplots(1,1) and the newcm assignment. > > Traceback (most recent call last): > File "colorbar_Mytest2.py", line 17, in <module> > f, ax = plt.subplots(1,1) > AttributeError: 'module' object has no attribute 'subplots' Ah, you must be using an older version of matplotlib  subplots is a (recently added) convenience shortcut for: f = plt.figure() ax = plt.subplot(1,1,1) It comes in handy when you're making lots of subplots by letting you do it with one call, instead of doing that one by one (as I have rewritten below, so you could run without having to upgrade your matplotlib. > Also, what does In and Out do, as in Out[68]: 0.34999? That's just the prompts from IPython  I *highly* recommend using IPython in place of the default python shell for interactive usage. In[10] is what I typed, Out[10] is the result of my command at In[10]. > Here are just a few of the errors I'm getting when executing > colorbar command with newcm. > Here's a simplified version that works for me: ouch! this code doesn't do quite what you want > from pylab import * Try to avoid doing this  because you will get unintended consequences such as the one on the following line. > vals = norm(np.linspace(14,40,1000)) This was meant to go *after* you initialize the 'norm' variable with norm = mpl.colors.Normalize(...). That's the norm I meant to be using. But because of the "from pylab import *" line, the norm function from numpy was imported  which is what was being used on that line as written in your code. so the vals= line is equivalent to vals = numpy.norm(np.linspace(14,40,1000)) which meant vals got assigned the value 886.25397758173483, and not at all what we wanted. We wanted it to get an array of 1000 numbers: vals = mpl.colors.Normalize(vmin=0, vmax=40)(np.linspace(14,40,1000)) That's where your trouble with newcm were coming from. Here's the complete example again, I've renamed the 'norm' variable to 'rawlins_norm' for clarity. import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib import cm import numpy as np # Make a figure and axes with dimensions as desired. fig = plt.figure(figsize=(8,3)) ax1 = plt.subplot(2,1,1) ax2 = plt.subplot(2,1,2) # Set the colormap and norm to correspond to the data for which # the colorbar will be used. rawlins_norm = mpl.colors.Normalize(vmin=0, vmax=40) # here set colorbar min/max # the right place for vals vals = rawlins_norm(np.linspace(14,40,1000)) newcm = cm.colors.ListedColormap(cm.hot_r(vals)) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cm.hot_r, norm=rawlins_norm, orientation='horizontal') cb1.set_label('"percent"') cb2 = mpl.colorbar.ColorbarBase(ax2, cmap=newcm, orientation='horizontal') cb2.set_label("colormap interval 0.01.0") plt.subplots_adjust(hspace=.7, bottom=.2) #comment out the next line to see the original (040 colormap) ax1.set_xlim(rawlins_norm((14,40))) plt.show() best,  Paul Ivanov 314 address only used for lists, offlist direct email at: http://pirsquared.org  GPG/PGP key id: 0x0F3E28F7 
From: Michael Rawlins <rawlins02@ya...>  20110106 12:43:27

Got it now. Sorry about the confusion...by working for me I meant that set of commands ran and made the standard colorbar. I just installed ipython (Ubuntu OS). Will try the interactive way as well. All very new. I've used PGPLOT for ~15 years. Thanks again. Mike  On Wed, 1/5/11, Paul Ivanov <pivanov314@...> wrote: > From: Paul Ivanov <pivanov314@...> > Subject: Re: [Matplotlibusers] defining a custom RGB colormap > To: matplotlibusers@... > Date: Wednesday, January 5, 2011, 7:15 PM > Michael Rawlins, on 20110105 > 14:42, wrote: > > Thanks for the detailed tutorial. I'm getting errors > when I > > attempt to use plt.subplots(1,1) and the newcm > assignment. > > > > Traceback (most recent call last): > > File "colorbar_Mytest2.py", line 17, > in <module> > > f, ax = plt.subplots(1,1) > > AttributeError: 'module' object has no attribute > 'subplots' > > Ah, you must be using an older version of matplotlib  > subplots > is a (recently added) convenience shortcut for: > > f = plt.figure() > ax = plt.subplot(1,1,1) > > It comes in handy when you're making lots of subplots by > letting > you do it with one call, instead of doing that one by one > (as I > have rewritten below, so you could run without having to > upgrade > your matplotlib. > > > Also, what does In and Out do, as in Out[68]: > 0.34999? > > That's just the prompts from IPython  I *highly* recommend > using > IPython in place of the default python shell for > interactive usage. > In[10] is what I typed, Out[10] is the result of my > command at > In[10]. > > > Here are just a few of the errors I'm getting when > executing > > colorbar command with newcm. > > > Here's a simplified version that works for me: > > ouch! this code doesn't do quite what you want > > > from pylab import * > > Try to avoid doing this  because you will get unintended > consequences such as the one on the following line. > > > vals = norm(np.linspace(14,40,1000)) > > This was meant to go *after* you initialize the 'norm' > variable > with norm = mpl.colors.Normalize(...). That's the norm I > meant to be using. But because of the "from pylab import *" > line, > the norm function from numpy was imported  which is what > was being > used on that line as written in your code. > > so the vals= line is equivalent to > > vals = numpy.norm(np.linspace(14,40,1000)) > > which meant vals got assigned the value 886.25397758173483, > and > not at all what we wanted. We wanted it to get an array of > 1000 > numbers: > > vals = mpl.colors.Normalize(vmin=0, > vmax=40)(np.linspace(14,40,1000)) > > That's where your trouble with newcm were coming from. > Here's the > complete example again, I've renamed the 'norm' variable > to > 'rawlins_norm' for clarity. > > import matplotlib as mpl > import matplotlib.pyplot as plt > from matplotlib import cm > import numpy as np > > # Make a figure and axes with dimensions as desired. > fig = plt.figure(figsize=(8,3)) > ax1 = plt.subplot(2,1,1) > ax2 = plt.subplot(2,1,2) > > # Set the colormap and norm to correspond to the data for > which > # the colorbar will be used. > rawlins_norm = mpl.colors.Normalize(vmin=0, > vmax=40) # here set colorbar min/max > # the right place for vals > vals = rawlins_norm(np.linspace(14,40,1000)) > newcm = cm.colors.ListedColormap(cm.hot_r(vals)) > > cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cm.hot_r, > > > norm=rawlins_norm, > > > orientation='horizontal') > > cb1.set_label('"percent"') > cb2 = mpl.colorbar.ColorbarBase(ax2, cmap=newcm, > > > orientation='horizontal') > > cb2.set_label("colormap interval 0.01.0") > plt.subplots_adjust(hspace=.7, bottom=.2) > > #comment out the next line to see the original (040 > colormap) > ax1.set_xlim(rawlins_norm((14,40))) > plt.show() > > > best, >  > Paul Ivanov > 314 address only used for lists, offlist direct > email at: > http://pirsquared.org  GPG/PGP key id: 0x0F3E28F7 > > Inline Attachment Follows > >  > Learn how Oracle Real Application Clusters (RAC) One Node > allows customers > to consolidate database storage, standardize their database > environment, and, > should the need arise, upgrade to a full multinode Oracle > RAC database > without downtime or disruption > http://p.sf.net/sfu/oraclesfdevnl > Inline Attachment Follows > > _______________________________________________ > Matplotlibusers mailing list > Matplotlibusers@... > https://lists.sourceforge.net/lists/listinfo/matplotlibusers > 
Sign up for the SourceForge newsletter:
No, thanks