[Matplotlib-users] GMT-like color maps
I'm trying to replicate the color-mapping behavior of the GMT package with matplotlib/basemap and the imshow() function, and have run into a problem. Using GMT you can assign colors to ranges of Z values, so that (for example), Z values between 0 and 50 are given a color interpolated between (0,0,255) (blue) and (255,0,0) (red). There have been various versions of a function called gmtColorMap() posted to this list. I did some experiments today, and as far as I can tell, this function only reads the _color_ part of a GMT .cpt file, ignoring the Z values to which those color ranges are assigned. This isn't a problem as long as you have a linear color scale. However, if you have (as in my case) a color scale assigned to non-linear ranges of values, it becomes a problem. Is there a way with imshow() to assign ranges of colors to specific ranges of Z values? As a test, I created the attached python script, which reads in the attached .cpt file. For those of you not aware of the GMT color palette file format, in each row you define two end points for your Z values, and two corresponding RGB triplets. In my simplified example, I have defined 8 ranges, and assigned a single color to each range. For example, the first two lines in my color palette file looks like this: 0 255 255 255 5 255 255 255 5 255 255 000 00050 255 255 000 which can be interpreted to mean that any values between 0 and 5 (filled in with zeros to make the columns line up), should be colored white. Similarly, any values between 5 and 50 should be colored yellow. popcpt.cpt Description: Binary data #!/usr/bin/python from matplotlib.colors import LinearSegmentedColormap,Normalize from pylab import * def gmtColormap(fileName): import colorsys import numpy as N try: f = open(fileName) except: print file ,fileName, not found return None lines = f.readlines() f.close() x = [] r = [] g = [] b = [] colorModel = RGB for l in lines: ls = l.split() if l[0] == #: if ls[-1] == HSV: colorModel = HSV continue else: continue if ls[0] == B or ls[0] == F or ls[0] == N: pass else: x.append(float(ls[0])) r.append(float(ls[1])) g.append(float(ls[2])) b.append(float(ls[3])) xtemp = float(ls[4]) rtemp = float(ls[5]) gtemp = float(ls[6]) btemp = float(ls[7]) x.append(xtemp) r.append(rtemp) g.append(gtemp) b.append(btemp) nTable = len(r) x = N.array( x , N.float32) r = N.array( r , N.float32) g = N.array( g , N.float32) b = N.array( b , N.float32) if colorModel == HSV: for i in range(r.shape[0]): rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i]) r[i] = rr ; g[i] = gg ; b[i] = bb if colorModel == HSV: for i in range(r.shape[0]): rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i]) r[i] = rr ; g[i] = gg ; b[i] = bb if colorModel == RGB: r = r/255. g = g/255. b = b/255. xNorm = (x - x[0])/(x[-1] - x[0]) red = [] blue = [] green = [] for i in range(len(x)): red.append([xNorm[i],r[i],r[i]]) green.append([xNorm[i],g[i],g[i]]) blue.append([xNorm[i],b[i],b[i]]) colorDict = {red:red, green:green, blue:blue} return (colorDict) colormap = 'popcpt.cpt' cdict = gmtColormap(colormap) palette = LinearSegmentedColormap('my_colormap',cdict) f = figure() data = array([[2,2,2,2,2], [25,25,25,25,25], [75,75,75,75,75], [250,250,250,250,250], [750,750,750,750,750], [2500,2500,2500,2500,2500], [7500,7500,7500,7500,7500], [25000,25000,25000,25000,25000]]) imshow(data,cmap=palette) #draw grid lines around all the cells nrows,ncols = data.shape for row in range(0,nrows): plot([0,ncols],[row,row],'k') for col in range(0,ncols): plot([col,col],[0,nrows],'k') axis([0,ncols-1,0,nrows]) colorbar() savefig('output.png') close('all') -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Re: [Matplotlib-users] GMT-like color maps
Hi Michael, I may be completely off my rocker here, but I think that you can define the range of Z values that the ramp should be applied to with the Normalize function. cmap = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict,256) norm = mpl.colors.Normalize(vmin=.0, vmax=1.0) I'm only guessing though, because at this point I only change vmin and vmax to alter the colorbar labels. Roger -- On Tue, Dec 16, 2008 at 1:15 PM, Michael Hearne mhea...@usgs.gov wrote: I'm trying to replicate the color-mapping behavior of the GMT package with matplotlib/basemap and the imshow() function, and have run into a problem. Using GMT you can assign colors to ranges of Z values, so that (for example), Z values between 0 and 50 are given a color interpolated between (0,0,255) (blue) and (255,0,0) (red). There have been various versions of a function called gmtColorMap() posted to this list. I did some experiments today, and as far as I can tell, this function only reads the _color_ part of a GMT .cpt file, ignoring the Z values to which those color ranges are assigned. This isn't a problem as long as you have a linear color scale. However, if you have (as in my case) a color scale assigned to non-linear ranges of values, it becomes a problem. Is there a way with imshow() to assign ranges of colors to specific ranges of Z values? As a test, I created the attached python script, which reads in the attached .cpt file. For those of you not aware of the GMT color palette file format, in each row you define two end points for your Z values, and two corresponding RGB triplets. In my simplified example, I have defined 8 ranges, and assigned a single color to each range. For example, the first two lines in my color palette file looks like this: 0 255 255 255 5 255 255 255 5 255 255 000 00050 255 255 000 which can be interpreted to mean that any values between 0 and 5 (filled in with zeros to make the columns line up), should be colored white. Similarly, any values between 5 and 50 should be colored yellow. #!/usr/bin/python from matplotlib.colors import LinearSegmentedColormap,Normalize from pylab import * def gmtColormap(fileName): import colorsys import numpy as N try: f = open(fileName) except: print file ,fileName, not found return None lines = f.readlines() f.close() x = [] r = [] g = [] b = [] colorModel = RGB for l in lines: ls = l.split() if l[0] == #: if ls[-1] == HSV: colorModel = HSV continue else: continue if ls[0] == B or ls[0] == F or ls[0] == N: pass else: x.append(float(ls[0])) r.append(float(ls[1])) g.append(float(ls[2])) b.append(float(ls[3])) xtemp = float(ls[4]) rtemp = float(ls[5]) gtemp = float(ls[6]) btemp = float(ls[7]) x.append(xtemp) r.append(rtemp) g.append(gtemp) b.append(btemp) nTable = len(r) x = N.array( x , N.float32) r = N.array( r , N.float32) g = N.array( g , N.float32) b = N.array( b , N.float32) if colorModel == HSV: for i in range(r.shape[0]): rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i]) r[i] = rr ; g[i] = gg ; b[i] = bb if colorModel == HSV: for i in range(r.shape[0]): rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i]) r[i] = rr ; g[i] = gg ; b[i] = bb if colorModel == RGB: r = r/255. g = g/255. b = b/255. xNorm = (x - x[0])/(x[-1] - x[0]) red = [] blue = [] green = [] for i in range(len(x)): red.append([xNorm[i],r[i],r[i]]) green.append([xNorm[i],g[i],g[i]]) blue.append([xNorm[i],b[i],b[i]]) colorDict = {red:red, green:green, blue:blue} return (colorDict) colormap = 'popcpt.cpt' cdict = gmtColormap(colormap) palette = LinearSegmentedColormap('my_colormap',cdict) f = figure() data = array([[2,2,2,2,2], [25,25,25,25,25], [75,75,75,75,75], [250,250,250,250,250], [750,750,750,750,750], [2500,2500,2500,2500,2500], [7500,7500,7500,7500,7500], [25000,25000,25000,25000,25000]]) imshow(data,cmap=palette) #draw grid lines around all the cells nrows,ncols = data.shape for row in range(0,nrows): plot([0,ncols],[row,row],'k') for col in range(0,ncols): plot([col,col],[0,nrows],'k') axis([0,ncols-1,0,nrows]) colorbar() savefig('output.png') close('all') -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future
Re: [Matplotlib-users] GMT-like color maps
Michael Hearne wrote: I'm trying to replicate the color-mapping behavior of the GMT package with matplotlib/basemap and the imshow() function, and have run into a problem. Using GMT you can assign colors to ranges of Z values, so that (for example), Z values between 0 and 50 are given a color interpolated between (0,0,255) (blue) and (255,0,0) (red). There have been various versions of a function called gmtColorMap() posted to this list. I did some experiments today, and as far as I can tell, this function only reads the _color_ part of a GMT .cpt file, ignoring the Z values to which those color ranges are assigned. This isn't a problem as long as you have a linear color scale. However, if you have (as in my case) a color scale assigned to non-linear ranges of values, it becomes a problem. Is there a way with imshow() to assign ranges of colors to specific ranges of Z values? Yes. See examples/pylab_examples/image_masked.py for an example of BoundaryNorm. The combination of a ListedColormap and a BoundaryNorm should provide exactly what you are describing. Eric As a test, I created the attached python script, which reads in the attached .cpt file. For those of you not aware of the GMT color palette file format, in each row you define two end points for your Z values, and two corresponding RGB triplets. In my simplified example, I have defined 8 ranges, and assigned a single color to each range. For example, the first two lines in my color palette file looks like this: 0 255 255 255 5 255 255 255 5 255 255 000 00050 255 255 000 which can be interpreted to mean that any values between 0 and 5 (filled in with zeros to make the columns line up), should be colored white. Similarly, any values between 5 and 50 should be colored yellow. -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users