Python Contour Plot with Discrete Colorbar

Programming scripts on how to read, analyze and access PO.DAAC data

Python Contour Plot with Discrete Colorbar

Postby yiboj » Thu Nov 23, 2017 9:33 pm

In this post, we create un-evenly distributed discrete colorbar, and also set the color for outbound contour values. Please check the attached python script:

Code: Select all
from matplotlib import pyplot as plt
import matplotlib as mpl
import numpy as np
from netCDF4 import Dataset

# Read in the Sea Surface Temperature Anomaly Dataset
ncin = Dataset('201210.ERSST.anomaly.nc', 'r')
sst = ncin.variables['sst'][:]
lons = ncin.variables['lon'][:]
lats = ncin.variables['lat'][:]
ncin.close()

sst = np.squeeze(sst)

# setup the plot
fig = plt.figure()

# create the first axes for the main plot
ax1 = fig.add_axes([0.1, 0.1, 0.75, 0.8])

# define the colormap
cmap = plt.cm.Reds
# extract all colors from the Reds map
cmaplist = [cmap(i) for i in range(cmap.N)]
# make the first color entry to be Blue
cmaplist[0] = (.0,.0,1.0,1.0)
# make the last color entry to be Black
cmaplist[cmap.N-1] = (.0,.0,.0,1.0)
# create the new map
cmap = cmap.from_list('My cmap', cmaplist, cmap.N)

# define the contour levels and normalize
clevels = [-2, -1, 0, 0.5, 1, 2, 3, 4]
norm = mpl.colors.BoundaryNorm(clevels, cmap.N)

# Create the filled contour plot
scat = ax1.contourf(lons, lats, sst, level=clevels, cmap=cmap, norm=norm, extend='both')

ax1.set_xlabel('Longitude', size=12)
ax1.set_ylabel('Latitude', size=12)

# create the second axes for the colorbar
ax2 = fig.add_axes([0.86, 0.1, 0.02, 0.8])

# create the colorbar
cb = mpl.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm, extend='both', spacing='proportional', ticks=clevels, boundaries=clevels)

ax2.set_ylabel('SST Difference (K)', size=12)

plt.show()


Here is the generated contour plot:
discrete_colorbar.png
Sea Surface Temperature Difference (K)
discrete_colorbar.png (74.77 KiB) Viewed 2330 times


User could also download the Docker image for this recipe from dockerhub, and run the recipe using jupyter nootbook:
https://hub.docker.com/r/podaacdatarecipes/colorbar_discrete/
yiboj
 
Posts: 79
Joined: Mon Mar 30, 2015 11:22 am

Re: Python Contour Plot with Discrete Colorbar

Postby rabernat » Mon Nov 27, 2017 12:12 pm

I wish you would use xarray rather than the low-level netCDF4 module for your examples.

Consider how much less boilterplate one has to write with xarray

Code: Select all
import xarray as xr.
ds = xr.open_dataset('ersst.201210.nc')
clevels = [-2, -1, 0, 0.5, 1, 2, 3, 4]
ds.ssta[0,0].plot.contourf(levels=clevels, extend='both', cmap='Reds')
rabernat
 
Posts: 4
Joined: Mon Dec 05, 2016 5:08 pm

Re: Python Contour Plot with Discrete Colorbar

Postby yiboj » Mon Nov 27, 2017 1:01 pm

Thanks for sharing the script.
xarray is definitely another powerful python package to access and plot the netCDF files.
yiboj
 
Posts: 79
Joined: Mon Mar 30, 2015 11:22 am

Re: Python Contour Plot with Discrete Colorbar

Postby batsc » Tue Dec 05, 2017 12:32 am

An alternative for a map plot with colorbar uses Iris:

Code: Select all
import iris
import iris.quickplot as qplt
import matplotlib.pyplot as plt

sst = iris.load_cube('ersst.201210.nc')
clevels = [-2, -1, 0, 0.5, 1, 2, 3, 4]
qplt.contourf(sst, levels=clevels, extend='both', cmap='Reds')
plt.show()


One can add coastlines using:
Code: Select all
plt.gca().coastlines()
You can also plot on different map projections by using the Cartopy library (note Cartopy is to replace Basemap: https://matplotlib.org/basemap/users/in ... nouncement).

xarray vs iris (https://github.com/SciTools/iris/issues/2244):
xarray
- a pandas-like API
- a representation of a dataset (collection of variables) where coordinates are shared
- has the ability to represent any netcdf data

iris
- a representation of bounded quantities
- full support for non-standard calendars (e.g 360 day, noleap etc.)
- interpolation and regridding
- supports the use and creation of standards (CF) compliant data
batsc
 
Posts: 4
Joined: Sat Jun 10, 2017 3:51 am

Re: Python Contour Plot with Discrete Colorbar

Postby frodo12 » Fri Nov 02, 2018 9:29 pm

Hello, yibog,

You can create a custom discrete colorbar quite easily by using a BoundaryNorm as a normalizer for your scatter. The quirky bit (in my method) is making 0 showups as grey.

For images, I often use the cmap.set_bad() and convert my data to a numpy masked array. That would be much easier to make 0 greys, but I couldn't get this to work with the scatter or the custom cmap.

As an alternative, you can make your own cmap from scratch, or read-out an existing one and override just some specific entries.

Thanks

Python Compiler
frodo12
 
Posts: 1
Joined: Fri Nov 02, 2018 9:21 pm


Return to Data Recipes

cron