[Matplotlib-users] GMT-like color maps

2008-12-16 Thread Michael Hearne
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

2008-12-16 Thread Roger André
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

2008-12-16 Thread Eric Firing
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