Colorbar with Multiple Color Maps

Colorbar with Multiple Color Maps

Postby yiboj » Wed Nov 01, 2017 2:01 pm

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 podaactools.py 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
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# 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.

  Parameters
  ----------
  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
  """

  bmargin=(1.0-float(height.strip('%'))/100.0)*0.5
  fheight = 1.0/len(imgh)
  cheight_float = (1.0-2.0*bmargin)*fheight
  cheight = "%.2f%%" % (cheight_float*100.0)
  offset=float(offset.strip('%'))/100.0
  label_offset=float(label_offset.strip('%'))/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),
                   bbox_transform=ax.transAxes,
                   borderpad=0,
                   )
       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),
                   bbox_transform=ax.transAxes,
                   borderpad=0,
                   )
       cb = plt.colorbar(imgh[i], cax=axins)
    cb.ax.tick_params(labelsize=ticksize)
    # Customize colorbar tick labels
    cb.set_ticks(vticks)

  if location == "horizontal":
    plt.text(bmargin+cheight_float*len(imgh)*0.5, offset+label_offset, label,
       horizontalalignment='center',
       verticalalignment='center',
       fontsize=labelsize,
       transform = ax.transAxes)
  else:
    plt.text(1.0+offset+label_offset, bmargin+cheight_float*len(imgh)*0.5, label,
       horizontalalignment='center',
       verticalalignment='center',
       rotation=90,
       fontsize=labelsize,
       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=https://podaac-tools.jpl.nasa.gov/drive/files/common/sw/recipes/mcolorbar/mcolorbar_test.py[/url]is listed below. It uses the 2010 October Sea Seurface Temperature data file from [url=https://podaac.jpl.nasa.gov/dataset/REYNOLDS_NCDC_L4_SST_HIST_RECON_MONTHLY_V3B_NETCDF]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 201210.ERSST.anomaly.nc 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('201210.ERSST.anomaly.nc', 'r')
sst = ncin.variables['sst'][:]
lons = ncin.variables['lon'][:]
lats = ncin.variables['lat'][:]
ncin.close()

sst = np.squeeze(sst)

print(sst.shape)

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.drawcoastlines(linewidth=0.25)
map.fillcontinents(color='0.8')

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)
cmap=plt.get_cmap("winter")
cs1=map.contourf(x, y, sst, clevs, cmap=cmap)

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

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

clevs = np.linspace(2.0, 3.0, 11)
cmap=plt.get_cmap("Reds")
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%")

plt.show()


The plot created using the above code is shown below:
mcolorbar.png
SST Anomaly with mcolorbar
mcolorbar.png (131.78 KiB) Viewed 12358 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_map/
yiboj
 
Posts: 130
Joined: Mon Mar 30, 2015 11:22 am

Return to Visualization

cron