Combine multiple line plot and contour plot with a colorbar using Python and matplotlib.pyplot


The result is:
Combine multiple line plot and contour plot with a colorbar using Python and matplotlib.pyplot

This code shows how to combine multiple line plots and contour plots with a colorbar in one figure using Python and matplotlib.pyplot. To combine these plots, plt.subplots with gridspec_kw options are used. The xlims are also adjusted between upper and lower plots.

This page is based on the following web pages:

In [1]:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

Generate the random data to show

In [2]:
nx,ny = 100,100
xmin,xmax = 0,10
ymin,ymax = 0,8
xs,ys = np.linspace(xmin, xmax, nx), np.linspace(ymin, ymax, ny)
XX,YY = np.meshgrid(xs, ys)
# values to be shown in coutour plot
ZZ1 = -1   +  2*np.random.rand(nx, ny)
ZZ2 = -0.5 +  1*np.random.rand(nx, ny)
ZZ3 = -0.25+0.5*np.random.rand(nx, ny)
# values to be shown in the line plot
zs1 = ZZ1[0]
zs2 = ZZ2[0]
zs3 = ZZ3[0]

Generate one figure with three line plots, three contour plots, and one colorbar

In [3]:
fig = plt.figure(facecolor='w', figsize=(10,5))
grid = fig.subplots(nrows=2, ncols=4,
                   gridspec_kw={'width_ratios':(1,1,1,0.07), 'height_ratios':(1,0.9)})
*axes1, cax1 = grid[0]
*axes2, cax2 = grid[1]
cax1.set_visible(False)

data1 = [zs1, zs2, zs3]
data2 = [ZZ1, ZZ2, ZZ3]
zmin, zmax = -1, 1
lvls = np.linspace(zmin, zmax, 30)

# Configure the datalimit and labels, the plot line and contour graoh
for ax1, ax2, d1, d2 in zip(axes1, axes2, data1, data2):
    ax1.set_ylim(zmin, zmax)
    ax2.set_aspect('equal', 'datalim')
    ax2.set_ylim(ymin, ymax)
    ax2.set_xlabel('x ticks')
    ax2.set_yticks(np.arange(ymin, ymax+0.001,2))
    ax1.plot(xs, d1, 'k-')
    cont = ax2.contourf(XX, YY, d2, levels=lvls, vmin=zmin, vmax=zmax, cmap='jet')
    # cont contains the contourf data at the axes[-1]
# Delete unneeded x and y ticklabels
for ax1 in axes1:
    plt.setp(ax1.get_xticklabels(), visible=False)    
for ax1,ax2 in zip(axes1[1:],axes2[1:]):
    plt.setp(ax1.get_yticklabels(), visible=False)
    plt.setp(ax2.get_yticklabels(), visible=False)

# Generate colorbar at cax2 based on the contour data of aces2[-1]
cbar = fig.colorbar(cont, cax=cax2)
cbar.set_clim(zmin, zmax)
cbar.set_ticks(np.arange(zmin, zmax+10**(-10),0.2))
# Set the labels of each axis\
cbar.set_label('Values in colormap')
axes1[0].set_ylabel('values')  # set ylabel
axes2[0].set_ylabel('y ticks') # set ylabel
axes1[0].yaxis.set_label_coords(-0.17, 0.5) # position of ylabel
axes2[0].yaxis.set_label_coords(-0.17, 0.5) # position of ylabel

# Adjust the figures, you have to draw all of the figures before the adjustment
fig.canvas.draw()
plt.tight_layout()
for ax1, ax2 in zip(axes1, axes2):
    ax1.set_xlim(ax2.get_xlim())

# Save the figure
plt.savefig('combine_multiple_line_contour_colorbar.png',
            bbox_inches='tight', pad_inches=0.02, dpi=150)