Home Ask Login Register

Developers Planet

Your answer is one click away!

James Warner February 2016

Color scale - close but not close enough

I'm trying to produce a plot which uses the same colorscale as the Met Office, so I can easily compare my plots to theirs. An example of theirs is at Here

My current closest effort is here: Here

I appreciate my code is messy - I couldn't find a way to set a color for values above a certain threshold (otherwise it goes white),hence the loop.

I would upload the NetCDF File but I haven't got a high enough rep to do this.

Many, many thanks in advance for any help.

My code for plotting is shown below;

from Scientific.IO.NetCDF import NetCDFFile                     
from mpl_toolkits.basemap import Basemap                     
from matplotlib import pyplot as plt                      
import numpy as np

myfile = NetCDFFile('ERA_Dec_89-94.nc', 'r')   
Lat = NetCDFFile('/home/james/Documents/Lat_Lon_NC_Files/latitudes_d02.nc','r')
Long = NetCDFFile('/home/james/Documents/Lat_Lon_NC_Files/longitudes_d02.nc','r')

XLAT = Lat.variables['XLAT'][:]     
XLONG = Long.variables['XLONG'][:]      
ERA_Data = myfile.variables['Monthlyrain'][:]

plot = np.zeros([1000,1730])

plot[:,:] = np.average(ERA_Data[:,:,:],axis=0)

m = Basemap(projection='merc',resolution='f',llcrnrlat=49,llcrnrlon=-11,urcrnrlat=61,urcrnrlon=3)
m.drawparallels(np.arange(-90., 91., 5.), labels=[1,0,0,0], fontsize=11)
m.drawmeridians(np.arange(-180., 181., 5.), labels=[0,0,0,1], fontsize=11)


for i in range(0,1729):
    for j in range(0,999):
         if plot[j,i] >250:
             plot[j,i] = 250.001
         if plot[j,i] < 40:
             plot[j,i] = 40

scale = [40,40.001,60,80,100,125,150,200,250, 250.001]
cs = m.contourf(X,Y,plot,scale, cmap='PuOr')
cbar = m.colorbar(cs, ticks=  [40.0005,50,70,90,112.5,137.5,175,225,250.0005])
cbar.set_ticklabels(['<40','40-60', '60-80        


xnx February 2016

If the issue is simply the colormap, you can pick the RGB components of the colors off your screen and turn them into a ListedColormap, mapped to the boundaries of the rainfall in the chart you give as an example. For example,

bounds = [0, 40, 60, 80, 100, 125, 150, 200, 250, 1000]
rgblist = [(51,0,0), (102,51,0), (153,102,51), (204,153,102), (255, 255, 255),
           (204,204,255), (153,153,255), (51,102,255), (0,0,153)]
clist = [[c/255 for  c in rgb] for rgb in rgblist]

from matplotlib import colors
cmap = colors.ListedColormap(clist)
norm = colors.BoundaryNorm(bounds, cmap.N)

ax.imshow(arr, cmap=cmap, norm=norm)

kazemakase February 2016

The first part (getting the colors right) was already answered. In order to restrict the values to a certain range you have several options.

  • Use cmap.set_over and cmap.set_under to set out-of-bounds colors, as described here

  • use np.clip instead of the loop to restrict the values to a certian range:

    plot = np.clip(plot, 40, 250)

Post Status

Asked in February 2016
Viewed 2,357 times
Voted 11
Answered 2 times


Leave an answer

Quote of the day: live life