One colorbar when plotting two different data sets next to each other

I have been trying to plot two data sets next to each other. Someone kindly suggested this method in a previous post. However I am now having trouble with getting only one colorbar for each of the data sets (so one colorbar for data1 and another for data2).

I am using a synthetic data set, but in my real data set I have pretty different maximum and minimum values say like -.4 to .4 or -.6 to .8, so with this example data set, how do I just make one colorbar for each of the two data sets?

There is a colorbar for each individual plot, but my goal is to have these 32 plots but just two colorbars: one for data set “data1” and another for data set “data2”.

This is what I have so far:

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import xarray as xr 

data1 = np.random.rand(16, 20, 15)
data2 = np.random.rand(16,20,15)


fig, axes = plt.subplots(nrows=8, ncols=4, figsize=(10,20))
axes = axes.ravel()

# plot the data in pairs
for i in range(16):
    data1 = axes[2*i].pcolormesh(data1[i])
    axes[2*i].set_title(f'data1[{i}]')
    cbar1 = fig.colorbar(x, fraction=.2,ax=axes[2*i])
    data2 = axes[2*i+1].pcolormesh(data2[i])
    axes[2*i+1].set_title(f'data2[{i}]')
    cbar2 = fig.colorbar(y, fraction=.2,ax=axes[2*i+1])

for ax in axes:
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.grid()
plt.tight_layout()
plt.show()

enter image description here

I also tried this way, which gives one colorbar… but I realize that it is just showing the colorbar of the last contour plot (since the colorbar function is not in the loop). and I would like there to be just one colorbar based on all the plots. This way is wrong* but an attempt at getting just one colorbar based on each of the data sets (data1 and data2).

fig, axes = plt.subplots(nrows=8, ncols=4, figsize=(10,20))
axes = axes.ravel()

# plot the data in pairs
for i in range(16):
    data1 = axes[2*i].pcolormesh(data1[i])
    axes[2*i].set_title(f'data1[{i}]')
    #cbar1 = fig.colorbar(x, fraction=.2,ax=axes[2*i])
    data2 = axes[2*i+1].pcolormesh(data2[i])
    axes[2*i+1].set_title(f'data2[{i}]')
    #cbar2 = fig.colorbar(y, fraction=.2,ax=axes[2*i+1])

for ax in axes:
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.grid()
    
cbaxes1 = fig.add_axes([1.02,.85,.05,.1]) 
cbar1 = fig.colorbar(data1, cax = cbaxes1, fraction=.02)
cbar1.set_label('data1',labelpad=15, y=.5, rotation=90,fontsize=20)

cbaxes = fig.add_axes([1.2,.85,.05,.1]) 
cbar = fig.colorbar(data2, cax = cbaxes, fraction=.02)
cbar.set_label('data2',labelpad=15, y=.5, rotation=90,fontsize=20)

plt.tight_layout()
plt.show()

enter image description here

Answer

I copied your code and ran it but it doesn’t work.

As far as I understand, you want to have just one single colorbar for all these subplots. Then why not just separately make one? I think your data all have the same x and y lim, so I don’t see the problem why not just separately make one.

fig, axes = plt.subplots(nrows=8, ncols=5, figsize=(10,20))
axes = axes.ravel()

for i in range(8):
    axes[(i+1)*5-1].axis('off')

axcbar = fig.add_subplot(1,2,2)
axcbar.axis('off')

f = axcbar.scatter(1,1, c=1, vmin=0, vmax=1, visible=False)
cbar = plt.colorbar(f)

Output:

enter image description here

Is that what you want?