Adnan
Adnan

Reputation: 61

How to add a representative color bar for hist2d subplot when scale is different?

I am trying to add a representative (one instead of two) color bar for 2 hist2d subplots. It is very easy to unite when the scale is same but in my case scale is not same e.g. first color bar upper limit is 6 while for second color bar limit is 14 and so on for other case. Here is my script:


t_arrival=ce['P_Time'];
t_0=t_arrival[70];
t_a=t_0 + timedelta(hours=72);
t_b=t_0 - timedelta(hours=72);

x_bins = np.linspace(-130.05, -129.95, 20);
y_bins = np.linspace(45.90, 46, 20);

df_b = df_lo[(df_lo['A_t'].between(t_b,t_0))];
y_b=df_b['lat'];
x_b=df_b['long'];

df_a = df_lo[(df_lo['A_t'].between(t_0,t_a))];
y_a=df_a['lat'];
x_a=df_a['long'];


fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,5), sharey=True)
b=ax1.hist2d(x_b, y_b, bins =[x_bins, y_bins], cmap='Blues')

ax1.set_xlim([-130.05, -129.95])
ax1.set_ylim([45.90, 46])
ax1.set_yticks([45.90, 45.925, 45.95, 45.975, 46])
ax1.set_xticks([-130.05, -130.025, -130, -129.975, -129.95])
cb1=plt.colorbar(b[3], ax=ax1, shrink=0.80)
cb1.set_label('Observations/day', fontsize=10)
ax1.set_ylabel('Latitude', fontsize=10)
ax1.set_xlabel('Longitude', fontsize=10)


a=ax2.hist2d(x_a, y_a, bins =[x_bins, y_bins], cmap='Blues')

ax2.set_xlim([-130.05, -129.95])
ax2.set_ylim([45.90, 46])
ax2.set_yticks([45.90, 45.925, 45.95, 45.975, 46])
ax2.set_xticks([-130.05, -130.025, -130, -129.975, -129.95])
cb2=plt.colorbar(a[3], ax=ax2, shrink=0.80)
cb2.set_label('Observations/day', fontsize=10)
#ax2.set_ylabel('Latitude', fontsize=10)
ax2.set_xlabel('Longitude', fontsize=10)


plt.tight_layout() 

Result is here:

enter image description here

Additionally, I want to normalize my x-scale same as y-scale, I don't know why it changes to 10 power.

Thank you!

Upvotes: 0

Views: 123

Answers (1)

Stef
Stef

Reputation: 30639

  1. You need to set vmin and vmax or norm. To get these values before drawing the histograms, you can do it manually by calling numpy hist2d to get the histograms and then pcolormesh with vmax obtained from both histograms.
  2. You can switch off the offset notation using set_useOffset
  3. Better use constrained layout to get two equally sized charts and one colorbar.

Minimal example:

import matplotlib.pyplot as plt
import numpy as np

x_bins = np.linspace(-130.05, -129.95, 20);
y_bins = np.linspace(45.90, 46, 20);

x_a = [-130] * 14
y_a = [45.95] * 14
x_b = x_a[:6]
y_b = y_a[:6]

h_a, xedges, yedges = np.histogram2d(x_a, y_a, bins=[x_bins, y_bins])
h_b, _, _ = np.histogram2d(x_b, y_b, bins=[x_bins, y_bins])
norm = plt.matplotlib.colors.Normalize(np.min((h_a, h_b)), np.max((h_a, h_b)))

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,5), sharey=True, sharex=True, layout='constrained')

cm_b = ax1.pcolormesh(xedges, yedges, h_b.T, norm=norm, cmap='Blues')
cm_a = ax2.pcolormesh(xedges, yedges, h_a.T, norm=norm, cmap='Blues')

ax1.set_xlim([-130.05, -129.95])
ax1.set_ylim([45.90, 46])
ax1.set_yticks([45.90, 45.925, 45.95, 45.975, 46])
ax1.set_xticks([-130.05, -130.025, -130, -129.975, -129.95])
ax1.xaxis.get_major_formatter().set_useOffset(False)
ax1.set_ylabel('Latitude', fontsize=10)
ax1.set_xlabel('Longitude', fontsize=10)
ax2.set_xlabel('Longitude', fontsize=10)

cb = fig.colorbar(cm_a, ax=ax2, shrink=0.80)
cb.set_label('Observations/day', fontsize=10)

enter image description here

Upvotes: 2

Related Questions