Page 1 of 1

Colorbar with Multiple Color Maps

PostPosted: Wed Nov 01, 2017 2:01 pm
by yiboj
In the python matlibplot package and other graphic producing packages such as IDL and Matlab, the colorbar function can only use one single colormap which may make it difficult to visualize or focus on the data in certain ranges.

We are currently in the process of developing the python podaactools package which will include many functions related to datasets. mcolorbar is one of them which we created to implement the colorbar with arbitrary number of colormaps.

The module mcolorbar is in package as listed below:
Code: Select all
# Copyright 2017 California Institute of Technology.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

def mcolorbar(imgh, ax, location="horizontal", width="5%", height="100%", offset="-15%", vticks=[], ticksize=10, label_offset="5", label="", labelsize=10):
  Add a multiple colormap colorbar to a plot.

  imgh         : list of image hangle returned from contour or img funtions
  ax           : current Axes instance, usually ax = plt.gca()
  location     : horizontal or vertical
  width        : in percentage
  height       : in percentage
  offset       : offset from the main plot in percentage
  ticksize     : tick size
  vticks       : tick value labels
  labelsize    : label size
  label        : colorbar label
  label_offset : offset from the main plot in percentage

  fheight = 1.0/len(imgh)
  cheight_float = (1.0-2.0*bmargin)*fheight
  cheight = "%.2f%%" % (cheight_float*100.0)
  for i in range(0,len(imgh)):
    if location == "horizontal":
       axins = inset_axes(ax, cheight, width, loc=3,
                   bbox_to_anchor=(bmargin+cheight_float*i, offset, 1, 1),
       cb = plt.colorbar(imgh[i], cax=axins, orientation="horizontal")
    elif location == "vertical":
       axins = inset_axes(ax, width, cheight, loc=3,
                   bbox_to_anchor=(1.0+offset, bmargin+cheight_float*i, 1, 1),
       cb = plt.colorbar(imgh[i], cax=axins)
    # Customize colorbar tick labels

  if location == "horizontal":
    plt.text(bmargin+cheight_float*len(imgh)*0.5, offset+label_offset, label,
       transform = ax.transAxes)
    plt.text(1.0+offset+label_offset, bmargin+cheight_float*len(imgh)*0.5, label,
       transform = ax.transAxes)

We need to import the podaactool package before we can use mcolor function as indicated below:
Code: Select all
import podaactools

The test file [url=[/url]is listed below. It uses the 2010 October Sea Seurface Temperature data file from [url=]Smith and Reynolds NCDC Level 4 Historical Reconstructed SST Monthly Version 3b netCDF[/url] (ERSST). The SST data anomaly is calculated by removing the climatology, and the data is in the range between -2 and 3 degreeF. User could download the test data file here. We use four colormaps: winter, cool, Wistia, and Reds to illustrate the functionality of the multiple colorbar.
Code: Select all
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
from netCDF4 import Dataset

import podaactools

ncin = Dataset('', 'r')
sst = ncin.variables['sst'][:]
lons = ncin.variables['lon'][:]
lats = ncin.variables['lat'][:]

sst = np.squeeze(sst)


nlon = len(lons)
nlat = len(lats)

map = Basemap(resolution='c', projection='cyl', llcrnrlon=0, llcrnrlat=-90, urcrnrlon=360, urcrnrlat=90)
#map = Basemap(resolution='c', projection='robin',lon_0=0)

parallels = np.arange(-90,90,30.)
meridians = np.arange(0,360,60)


map.drawparallels(parallels,labels=[1,0,0,0],color='w', fontsize=10, fontweight='bold')
meri = map.drawmeridians(meridians,labels=[0,0,0,1],color='w', fontsize=10, fontweight='bold')

x, y = map(*np.meshgrid(lons, lats))

clevs = np.linspace(-1.0, 0.0, 21)
cs1=map.contourf(x, y, sst, clevs, cmap=cmap)

clevs = np.linspace(0.0, 1.0, 11)
cs2=map.contourf(x, y, sst, clevs, cmap=cmap)

clevs = np.linspace(1.0, 2.0, 11)
cs3=map.contourf(x, y, sst, clevs, cmap=cmap)

clevs = np.linspace(2.0, 3.0, 11)
cs4=map.contourf(x, y, sst, clevs, cmap=cmap)

imgh = [cs1, cs2, cs3, cs4]

ax = plt.gca()

podaactools.mcolorbar(imgh, ax, location="horizontal", width="5%", height="100%", offset="-15%",
                      vticks=range(-3,4,1), ticksize=10,
                      label='SST Anomaly (defreeF)', labelsize=12, label_offset="-8%")
podaactools.mcolorbar(imgh, ax, location="vertical", width="3%", height="100%", offset="3%",
                      vticks=range(-3,4,1), ticksize=10,
                      label='SST Anomaly (defreeF)', labelsize=12, label_offset="6%")

The plot created using the above code is shown below:
SST Anomaly with mcolorbar
mcolorbar.png (131.78 KiB) Viewed 13961 times

User could also download the Docker image for this recipe from dockerhub, and run the recipe using jupyter nootbook: