6

The issue

I have a plot I'm trying to make for trends of precipitation rates around the world using gridded data. I can make the plot itself fine, but the color range is giving me issues. I can't figure out how to make the colormap better fit my data, which seems exponential. I tried a logarithmic range, but it doesn't quite fit the data right.

The code & data range

Here's what my 8,192 data values look like when plotted in order on a simple x-y line plot. Data points are on the x-axis & values are on the y-axis. enter image description here

Here's what my data looks like plotted with a LogNormal color range. It's too much mint green & orange-red for me.

#Set labels
lonlabels = ['0','45E','90E','135E','180','135W','90W','45W','0']
latlabels = ['90S','60S','30S','Eq.','30N','60N','90N']

#Set cmap properties
norm = colors.LogNorm() #creates logarithmic scale

#Create basemap
fig,ax = plt.subplots(figsize=(15.,10.))
m = Basemap(projection='cyl',llcrnrlat=-90,urcrnrlat=90,llcrnrlon=0,urcrnrlon=360.,lon_0=180.,resolution='c')
m.drawcoastlines(linewidth=1)
m.drawcountries(linewidth=1)
m.drawparallels(np.arange(-90,90,30.),linewidth=0.3)
m.drawmeridians(np.arange(-180.,180.,45.),linewidth=0.3)   
meshlon,meshlat = np.meshgrid(lon,lat)
x,y = m(meshlon,meshlat)

#Plot variables
trend = m.pcolormesh(x,y,lintrends[:,:,0],cmap='jet', norm=norm, shading='gouraud')

#Set plot properties
#Colorbar
cbar=m.colorbar(trend, size='8%',location='bottom',pad=0.8) #Set colorbar
cbar.set_label(label='Linear Trend (mm/day/decade)',size=25) #Set label
for t in cbar.ax.get_xticklabels():
     t.set_fontsize(25) #Set tick label sizes
#Titles & labels
fig.suptitle('Linear Trends of Precipitation (CanESM2)',fontsize=40,x=0.51,y=0.965)
ax.set_title('a) 1979-2014 Minimum Trend',fontsize=35)
ax.set_xticks(np.arange(0,405,45))
ax.set_xticklabels(lonlabels,fontsize=20)
ax.set_ylabel('Latitude',fontsize=25)
ax.set_yticks(np.arange(-90,120,30))
ax.set_yticklabels(latlabels,fontsize=20)

enter image description here

And here's what it looks like with a default, unaltered color range. (Same code minus the norm=norm argument.)

enter image description here

The question

Is there a mathematical scheme I can use to create a colormap that better shows the range of my data? Or do I need to make a custom range?

ChristineB
  • 1,283
  • 6
  • 15
  • 35
  • 2
    So if it is the colors you don't like, you can choose a different colormap. Here is a list of possible colormaps. http://matplotlib.org/examples/color/colormaps_reference.html. You might also want to check if the `PowerNorm`instead of the `LogNorm` is better for what you want to show. – cel Jul 29 '16 at 17:51
  • It's not so much the colors themselves as it is the range. If I could get more blues, cyans, and yellows to show up on the map, I'd be happy. Anyway, I played around with PowerNorm earlier and it didn't seem to work, but I just tried it again & after I set vmax = 3, now it looks more even, albeit a bit heavy on the dark blues for all the zero values. (Not much I can do about that.) Post this as an answer and I'll accept it. – ChristineB Jul 29 '16 at 18:08
  • On a related note: [please do not use the jet colormap](http://stats.stackexchange.com/questions/223315/why-use-colormap-viridis-over-jet). Because the yellow part of the colormap is brighter than the red or blue parts, it draws attention to the median values of your array, which are the least interesting from a data visualization point of view. There are [plenty of more appropriate colormaps](http://matplotlib.org/users/colormaps.html) which will help your plots look better :). – Andreq Jul 30 '16 at 18:30
  • A jet-like rainbow colormap is actually the standard in my field for depicting precipitation plots. – ChristineB Aug 01 '16 at 18:09
  • The other thing you can try is the SymLogNorm. Typically you use it when you need logarithmic scaling with positive and negative values, but it does also work when you want to split between a linear and logarithmic range. – Elliot Aug 25 '16 at 12:15

1 Answers1

0

A hack

You could try applying a maximum value, i.e. for any value above 2 simply replace it with 2.

Then you would have a single color (the maximum) representing 2+ and the rest of the colors would be spread across your data more evenly.

Community
  • 1
  • 1
Graeme Stuart
  • 4,782
  • 1
  • 20
  • 42
  • I did do that eventually, but I also needed to switch my normalization to PowerNorm & play around with the scale. – ChristineB Aug 25 '16 at 21:21