Beautiful colormaps for oceanography: cmocean

This package contains colormaps for commonly-used oceanographic variables. Most of the colormaps started from matplotlib colormaps, but have now been adjusted using the viscm tool to be perceptually uniform.

Here is our gallery:

import cmocean
cmocean.plots.plot_gallery()

(Source code, png, hires.png, pdf)

_images/index-1.png

These colormaps were chosen to be perceptually uniform and to reflect the data they are representing in terms of being sequential, divergent, or cyclic (phase colormap), and to be intuitive. For example, the algae colormap is shades of green which could represent chlorophyll.

Here is the lightness of the colormaps:

import cmocean
cmocean.plots.plot_lightness()

(Source code, png, hires.png, pdf)

_images/index-2.png

It is probably better to think in cam02ucs colorspace, in which Euclidean distance is made to be equivalent to changes in human perception. Plots of these colormaps in this colorspace and with some other important properties are seen using the viscm tool.

Here are some properties from the haline colormap. We can see that the colormap prints nicely to grayscale, has consistent perceptual deltas across the colormap, and good viewability for people with color blindness. It has a smooth representation in its 3D colorspace, and detail in the images is clear.

import cmocean
cmocean.plots.wrap_viscm(cmocean.cm.haline)

(Source code, png, hires.png, pdf)

_images/index-3.png

All of the evaluations of the colormaps using the viscm tool are shown in the page cmocean colormaps in viscm tool.

Colormap details

thermal

The thermal colormap is sequential with dark blue representing lower, cooler values and transitioning through reds to yellow representing increased warmer values.

http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_540/plots/sci_water_temp.png
http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_541/plots/sci_water_temp.png

Glider data from Texas A&M’s Geochemical and Environmental Research Group (GERG).

http://pong.tamu.edu/~kthyng/movies/txla_plots/temp/2004-07-30T00.png

Model output in the northwest Gulf of Mexico from the Physical Oceanography Numerical Group (PONG) at Texas A&M.

haline

The haline colormap is sequential, and might be used with dark blue representing lower salinity or fresher water, transitioning through greens to light yellow representing increased salinity or saltier water. This colormap is based on matplotlib’s YlGnBu, but was recreated from scratch using the viscm tool.

http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_540/plots/calc_salinity.png
http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_541/plots/calc_salinity.png

Glider data from Texas A&M’s Geochemical and Environmental Research Group (GERG).

http://pong.tamu.edu/~kthyng/movies/txla_plots/salt/2010-07-30T00.png

Model output in the northwest Gulf of Mexico from the Physical Oceanography Numerical Group (PONG) at Texas A&M.

http://clarkrichards.org/figure/source/2016-04-25-making-section-plots/plot2-1.png

Plotting CTD data (temperature and salinity) with the R oce package, by Clark Richards

solar

The solar colormap is sequential from dark brown for low values to increasingly bright yellow to potentially represent an increase in radiation in the water.

https://plot.ly/~empet/13620.png

Histogram from plotly.

ice

The ice colormap is sequential from very dark blue (almost black) to very light blue (almost white). A use for this could be representations of sea ice.

http://www.mathworks.com/matlabcentral/mlc-downloads/downloads/submissions/50126/versions/4/previews/seaice/html/SeaIceTimeSeries_20160620.gif

An example is provided by Chad Greene showing sea ice concentration around Antarctica.

gray

The gray colormap is sequential from black to white, with uniform steps through perceptual colorspace. This colormap is generic to be used for any sequential dataset.

import cmocean
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 3))
ax = fig.add_subplot(1, 2, 1)
cmocean.plots.test(cmocean.cm.gray, ax=ax)
ax = fig.add_subplot(1, 2, 2)
cmocean.plots.quick_plot(cmocean.cm.gray, ax=ax)

(Source code, png, hires.png, pdf)

_images/index-4.png

oxy

The oxy colormap is sequential for most of the colormap, representing the normal range of oxygen saturation in ocean water, and diverging 80% of the way into the colormap to represent a state of supersaturation. The bottom 20% of the colormap is colored reddish to highlight hypoxic or low oxygen water, but to still print relatively seamlessly into grayscale in case the red hue is not important for an application. The top 20% of the colormap, after the divergence, is colored yellow to highlight the supersaturated water. The minimum and maximum values of this colormap are meant to be controlled in order to properly place the low oxygen and supersaturated oxygen states properly. This colormap was developed for the Mississippi river plume area where both low and supersaturated conditions are regularly seen and monitored.

https://cloud.githubusercontent.com/assets/3487237/16996267/85ac01ea-4e7e-11e6-9801-ee97f7e65940.png

Model output in the northwest Gulf of Mexico from the Physical Oceanography Numerical Group (PONG) at Texas A&M. A simulation of bottom oxygen using a simple parameterization of bottom oxygen utilization reveals the complex structure of bottom oxygen. While the area affected by hypoxia stretches nearly 400 km along the shelf, variability on much smaller scales, down to a few kilometers, is also evident. The position of the Mississippi/Atchafalaya river plume, and instabilities present within the plume, determine the extent and structure of the hypoxic bottom waters. By Veronica Ruiz at Texas A&M.

deep

The deep colormap is sequential from light yellow to potentially represent shallower water through pale green to increasingly dark blue and purple to represent increasing depth.

https://cloud.githubusercontent.com/assets/3487237/16900541/4af66c4c-4bf5-11e6-92a9-82eaa39cb18b.png

Bathymetry plot, by Iury Sousa

dense

The dense colormap is sequential with whitish-blue for low values and increasing in purple with increasing value, which could be used to represent an increase in water density. Two examples of this colormap are shown below, from Texas A&M University gliders. This colormap is based on matplotlib’s Purples, but was recreated from scratch using the viscm tool.

http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_540/plots/calc_density.png http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_541/plots/calc_density.png

algae

The algae colormap is sequential with whitish-green for low values and increasing in green with increasing value, which could be used to represent an increase in chlorophyll in the water. Two examples of this colormap are shown below, from Texas A&M University gliders. This colormap is based on matplotlib’s Greens, but was recreated from scratch using the viscm tool.

http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_541/plots/sci_flbbcd_chlor_units.png

matter

The matter colormap is sequential with whitish-yellow for low values and increasing in pink with increasing value, and could be used to represent an increase in material in the water. Two examples of this colormap are shown below, from Texas A&M University gliders.

http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_540/plots/sci_flbbcd_cdom_units.png http://gcoos2.tamu.edu/gandalf_data/deployments/tamu/unit_541/plots/sci_flbbcd_cdom_units.png

turbid

The turbid colormap is sequential from light to dark brown and could be used to represent an increase in sediment in the water.

import cmocean
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 3))
ax = fig.add_subplot(1, 2, 1)
cmocean.plots.test(cmocean.cm.turbid, ax=ax)
ax = fig.add_subplot(1, 2, 2)
cmocean.plots.quick_plot(cmocean.cm.turbid, ax=ax)

(Source code, png, hires.png, pdf)

_images/index-5.png

speed

The speed colormap is sequential from light greenish yellow representing low values to dark yellowish green representing large values. This colormap is the positive half of the delta colormap. An example of this colormap is from a numerical simulation of the Texas and Louisiana shelf.

http://pong.tamu.edu/~kthyng/movies/txla_plots/speed/2010-07-30T00.png

amp

The amp colormap is sequential from whitish to dark red and could be used to represent an increase in wave height values. This colormap is the positive half of the balance colormap.

https://cloud.githubusercontent.com/assets/3487237/16920916/840d91d4-4cdd-11e6-8db5-f93cd61b78c2.png

Earthquake magnitude, by Natalie Accardo using GMT.

tempo

The tempo colormap is sequential from whitish to dark teal and could be used to represent an increase in wave period values. This colormap is the negative half of the curl colormap.

import cmocean
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 3))
ax = fig.add_subplot(1, 2, 1)
cmocean.plots.test(cmocean.cm.tempo, ax=ax)
ax = fig.add_subplot(1, 2, 2)
cmocean.plots.quick_plot(cmocean.cm.tempo, ax=ax)

(Source code, png, hires.png, pdf)

_images/index-6.png

phase

The phase colormap is circular, spanning all hues at a set lightness value. This map is intended to be used for properties such as wave phase and tidal phase which wrap around from 0˚ to 360˚ to 0˚ and should be represented without major perceptual jumps in the colormap. An example for a circular plot is shown below.

import cmocean
import matplotlib.pyplot as plt
import numpy as np

azimuths = np.arange(0, 361, 1)
zeniths = np.arange(40, 70, 1)
values = azimuths * np.ones((30, 361))
fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
ax.pcolormesh(azimuths*np.pi/180.0, zeniths, values, cmap=cmocean.cm.phase)
ax.set_yticks([])

(Source code, png, hires.png, pdf)

_images/index-7.png

balance

The balance colormap is diverging with dark blue to off-white to dark red representing negative to zero to positive values; this could be used to represent sea surface elevation, with deviations in the surface elevations as shades of color away from neutral off-white. In this case, shades of red have been chosen to represent sea surface elevation above the reference value (often mean sea level) to connect with warmer water typically being associated with an increase in the free surface, such as with the Loop Current in the Gulf of Mexico. An example of this colormap is from a numerical simulation of the Texas and Louisiana shelf. This colormap is based on matplotlib’s RdBu, but was recreated from scratch using the viscm tool.

http://pong.tamu.edu/~kthyng/movies/txla_plots/ssh/2010-07-30T00.png

delta

The delta colormap is diverging from darker blues to just off-white through shades of yellow green and could be used to represent diverging velocity values around a critical value (usually zero). This colormap was inspired by Francesca Samsel’s similar colormap, but generated from scratch using the viscm tool.

https://pbs.twimg.com/media/CkIWDFRWkAEdArC.jpg

From plotly.

http://pong.tamu.edu/~kthyng/movies/txla_plots/u/2010-07-30T00.png

Model output in the northwest Gulf of Mexico from the Physical Oceanography Numerical Group (PONG) at Texas A&M.

curl

The curl colormap is diverging from darker teal to just off-white through shades of magenta and could be used to represent diverging vorticity values around a critical value (usually zero). An example of this colormap is from a numerical simulation of the Texas and Louisiana shelf.

http://pong.tamu.edu/~kthyng/movies/txla_plots/vort/2010-07-30T00.png

Capabilities

The colormaps are all available in cmocean.cm. They can be accessed, and simply plotted, as follows:

import cmocean
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 3))
ax = fig.add_subplot(1, 2, 1)
cmocean.plots.test(cmocean.cm.thermal, ax=ax)
ax = fig.add_subplot(1, 2, 2)
cmocean.plots.quick_plot(cmocean.cm.algae, ax=ax)

(Source code, png, hires.png, pdf)

_images/index-8.png

All available colormap names can be accessed with cmocean.cm.cmapnames:

In [1]: import cmocean

In [2]: cmocean.cm.cmapnames
Out[2]: 
['thermal',
 'haline',
 'solar',
 'ice',
 'gray',
 'oxy',
 'deep',
 'dense',
 'algae',
 'matter',
 'turbid',
 'speed',
 'amp',
 'tempo',
 'phase',
 'balance',
 'delta',
 'curl']

The colormap instances can be accessed with:

In [3]: import cmocean

In [4]: cmaps = cmocean.cm.cmap_d;

Print all of the available colormaps to text files with 256 rgb entries with:

cmaps = cmocean.cm.cmap_d

cmocean.tools.print_colormaps(cmaps)

Output a dictionary to define a colormap with:

In [5]: import cmocean

In [6]: cmdict = cmocean.tools.get_dict(cmocean.cm.matter, N=9)

In [7]: print(cmdict)
{'blue': [(0.0, 0.69109690224984077, 0.69109690224984077), (0.125, 0.53031307900834646, 0.53031307900834646), (0.25, 0.40291681995676154, 0.40291681995676154), (0.375, 0.32938102171259315, 0.32938102171259315), (0.5, 0.33885361881305626, 0.33885361881305626), (0.625, 0.37820659039971588, 0.37820659039971588), (0.75, 0.38729596513525039, 0.38729596513525039), (0.875, 0.33739313395770171, 0.33739313395770171), (1.0, 0.24304267442183591, 0.24304267442183591)], 'green': [(0.0, 0.93032779532320797, 0.93032779532320797), (0.125, 0.75576791099973906, 0.75576791099973906), (0.25, 0.58413112562241909, 0.58413112562241909), (0.375, 0.41389524263548055, 0.41389524263548055), (0.5, 0.26372603126828165, 0.26372603126828165), (0.625, 0.16249519232276352, 0.16249519232276352), (0.75, 0.10922326738769267, 0.10922326738769267), (0.875, 0.089677516287552023, 0.089677516287552023), (1.0, 0.05913348735199072, 0.05913348735199072)], 'red': [(0.0, 0.99429361496112023, 0.99429361496112023), (0.125, 0.97669801635856757, 0.97669801635856757), (0.25, 0.94873479766923496, 0.94873479766923496), (0.375, 0.90045567698531204, 0.90045567698531204), (0.5, 0.80852468744463613, 0.80852468744463613), (0.625, 0.67108411902889908, 0.67108411902889908), (0.75, 0.51122751026810531, 0.51122751026810531), (0.875, 0.34246319725680402, 0.34246319725680402), (1.0, 0.18517171283533682, 0.18517171283533682)]}

Make a colormap instance with cmap = cmocean.tools.cmap(rgbin, N=10) given the rgb input array.

Reversed versions of all colormaps are available by appending “_r” to the colormap name, just as in matplotlib:

import cmocean
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 3))
ax = fig.add_subplot(1, 2, 1)
cmocean.plots.test(cmocean.cm.gray, ax=ax)
ax = fig.add_subplot(1, 2, 2)
cmocean.plots.test(cmocean.cm.gray_r, ax=ax)
fig.tight_layout()

(Source code, png, hires.png, pdf)

_images/index-9.png

Resources

Here are some of my favorite resources.

cmocean available elsewhere!

Examples of beautiful visualizations:

  • Earth wind/currents/temperature/everything visualization: This is a wonderful visualization of worldwide wind and ocean dynamics and properties. It is also great for teaching, and seems to be continually under development and getting new fields as plotting options.
  • This fall foliage map is easy to use, clear, and eye-catching. It is what we all aspire to!
  • A clever visualization from The Upshot of political leaning depending on birth year. This is a perfect use of the diverging red to blue colormap.

Why jet is a bad colormap, and how to choose better:

There is a series of talks from the SciPy conference from 2014 and 2015 talking about colormaps:

  • Damon McDougall introducing the problem with jet for representing data.
  • Kristen Thyng following up with how to choose better colormaps, including using perceptually uniform colormaps and considering whether the information being represented is sequential or diverging in nature.
  • Nathaniel Smith and Stéfan van der Walt explaining more about the jet colormap being bad, even bad for your health! They follow this up by proposing a new colormap for matplotlib, a Python plotting library.
  • Kristen Thyng building off the work done by Nathaniel and Stéfan, a proposal of colormaps to plot typical oceanographic quantities (which led to cmocean!).

Other tips for making good figures:

Tools for making nice figures:

  • Seaborn will help you make very nice looking statistical plots.

Contact

Kristen Thyng is the main developer of cmocean. Please email with questions, comments, and ideas. I’m collecting examples of the colormaps being used in action (see above) and also users of the colormaps, so I’d love to hear from you if you are using cmocean. kthyng at gmail.com

Indices and tables