Plotting Maps in pyshtools

pyshtools allows for the creation of publication quality images of geographical data with a minimum of effort. A basic image can be created simply by using the plot() method of an SHGrid class instance, and a variety of customizations can be specified by adding human-readable arguments. In this notebook, we demonstrate the major features of this plotting routine, which include

  1. Colormaps
  2. Colorbars
  3. Ticks and Labels
  4. Map Projections
  5. Creating Subplots

To demonstrate these features, we will make use of a few optional modules that will need to be installed. cartopy and pygmt allow for geographic projections, and palettable provides easy access to some useful scientific color maps.


In [1]:
import pyshtools as pysh
import matplotlib.pyplot as plt

from cartopy import crs as ccrs
import pygmt
from palettable import scientific as scm

%config InlineBackend.figure_format = 'retina'  # if you are not using a retina display, comment this line!

For our example, we will make use of the spherical harmonic coefficients of the shape of Mars. We read the coefficients from file, divide by 1000 to convert to km, set both the degree 0 and flattening terms to zero, expand the coefficients on a grid, and then plot the grid using default options.


In [2]:
clm = pysh.SHCoeffs.from_file('../ExampleDataFiles/MarsTopo719.shape') / 1000.
clm.coeffs[0,0,0] = 0.
clm.coeffs[0,2,0] = 0.
grid = clm.expand()

fig, ax = grid.plot(show=False)  # show=False is used only to avoid warnings when executing as a jupter notebook


The plot() method returns a matplotlib figure and its corresponding axes. When projecting data using pygmt, only a pygmt.Figure instance is returned.

1. Colormaps

The default colormap for pyshtools is 'viridis', which is both perceptually uniform and optimized for people with the most common form of color-vision deficiency. The first thing we can do is to select a different colormap. When using matplotlib colormaps, it is only necessary to specify the argument cmap and provide the name (as a string) of the colormap. For this example, we choose the matplotlib colormap 'RdBu' that goes from red to blue:


In [3]:
fig, ax = grid.plot(cmap='RdBu',
                    show=False)


You might find it odd that the hot colors are located at low elevations of the planet, so we can reverse the color progression with the option cmap_reverse:


In [4]:
fig, ax = grid.plot(cmap='RdBu',
                    cmap_reverse=True,
                    show=False)


This looks more natural, but because of the high dynamic range of the surface relief in the volcanic Tharsis province, the majority of the image uses colors that cover only a small range of the colormap. We can change the minimum and maximum data values used in generating the colormap by use of the option cmap_limits, and here, we set the bounds to -6 and 10 km:


In [5]:
fig, ax = grid.plot(cmap='RdBu',
                    cmap_reverse=True,
                    cmap_limits=[-6, 10],
                    show=False)


The colormaps are by default continuous. To instead use a colormap with constant colors over a specified data interval, it is only necessary to add an optional interval to cmap_limits. Here, we use an interval of 2 km:


In [6]:
fig, ax = grid.plot(cmap='RdBu',
                    cmap_reverse=True,
                    cmap_limits=[-6, 10, 2],
                    show=False)


Lastly, you can also use your own custom matplotlib colormaps. Here we use one of the scientific color maps (which are all perceptually uniform), and convert it to matplotlib format by adding .mpl_colormap. The scientifitic color maps are categorized as being either diverging or sequential, and here we choose the diverging 'Vik' colormap (the number 20 specifies the number of entries in the look-up table):


In [7]:
mycmap = scm.diverging.Vik_20.mpl_colormap
fig, ax = grid.plot(cmap=mycmap,
                    cmap_limits=[-6, 10],
                    show=False)


2. Colorbars

Colorbars are critical for interpretting the data plotted in an image. To add a colorbar to an image, it is only necessary to provide the argument colorbar with a value of 'top', 'bottom', 'left', or 'right':


In [8]:
fig, ax = grid.plot(cmap=mycmap,
                    colorbar='bottom',
                    show=False)


This by itself is not to useful, because we don't know what is being plotted and what the units are. To add a label to the colorbar, it is only necessary to specify cb_label:


In [9]:
fig, ax = grid.plot(cmap=mycmap,
                    colorbar='right',
                    cb_label='Elevation, km',
                    show=False)


If you would instead like to specify the units on the top of the colorbar (or to the right for horizontal colorbars), you can specify cb_ylabel:


In [10]:
fig, ax = grid.plot(cmap=mycmap,
                    colorbar='right',
                    cb_label='Elevation',
                    cb_ylabel='km',
                    show=False)