The result is:
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:
- matplotlibのcolorbarを解剖してわかったこと、あるいはもうcolorbar調整に苦労したくない人に捧げる話 - Qiita - URL: https://qiita.com/skotaro/items/01d66a8c9902a766a2c0 (in Japanese)
- Matplotlib 2 Subplots, 1 Colorbar - stackoverflow - URL: https://stackoverflow.com/questions/13784201/matplotlib-2-subplots-1-colorbar
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)