I am trying to add a colorbar to a chart that has a secondary y-axis. A minimal-ish example of my difficulties is given below. The trouble is that I cannot add a colorbar to an AxesSubplot object, and adding it directly as plt.colorbar puts it on top of my graph- see how it overlaps the rightmost y-axis. How can I fix this? Cheers.
import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate
time=[]
temp=[]
temp_f=[]
height=[]
for ti in np.arange( 0, 10, 0.5 ):
for te in np.arange( -12, 12, 0.5 ):
height.append( np.sqrt(1+ti)/(1+te*te)+ti*te/12.5 )
time.append(ti)
temp.append(te)
temp_f.append( 32+9.0*te/5)
time=np.array(time)
temp=np.array(temp)
temp_f=np.array(temp_f)
height=np.array(height)
xi, yi = np.linspace(time.min(), time.max(),25), np.linspace(temp.min(), temp.max(), 25)
xi, yi = np.meshgrid(xi, yi)
rbf = scipy.interpolate.Rbf(time, temp, height, function='linear')
zi = rbf(xi, yi)
fig = plt.figure()
ax1 = plt.gca()
ax1.set_xlabel( "Time (s)" )
ax1.set_ylabel( "Celsius" )
ax2 = ax1.twinx()
ax2.set_ylabel( "Fahrenheit" )
ax2.set_ylim( [temp_f.min(), temp_f.max()] )
img = ax1.imshow( zi, vmin=height.min(), vmax=height.max(), origin='lower',
extent=[time.min(), time.max(), temp.min(), temp.max()],
aspect='auto', cmap='YlOrRd')
plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1)
plt.show()
See positioning the colorbar.
You can manually specify the location of the colorbar by:
cbaxes = fig.add_axes([1, 0.15, 0.03, 0.7])
plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1, cax=cbaxes)
plt.colorbar does a good job for simple plots with one axes. With more complex setups it can get confused. So it is better to manually setup the axes for the colorbar. You can use the subplots function for that. By supplying gridspec_kw you can tell the underlying GridSpec object how you want the widths to be specified:
fig, [ax1, cax] = plt.subplots(1,2, gridspec_kw=dict(width_ratios=[10,1]))
when creating the colorbar you want to specify the axes which should be used to create the colorbar in:
plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1, cax=cax)
So with the full code:
import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate
time=[]
temp=[]
temp_f=[]
height=[]
for ti in np.arange( 0, 10, 0.5 ):
for te in np.arange( -12, 12, 0.5 ):
height.append( np.sqrt(1+ti)/(1+te*te)+ti*te/12.5 )
time.append(ti)
temp.append(te)
temp_f.append( 32+9.0*te/5)
time=np.array(time)
temp=np.array(temp)
temp_f=np.array(temp_f)
height=np.array(height)
xi, yi = np.linspace(time.min(), time.max(),25), np.linspace(temp.min(), temp.max(), 25)
xi, yi = np.meshgrid(xi, yi)
rbf = scipy.interpolate.Rbf(time, temp, height, function='linear')
zi = rbf(xi, yi)
fig, [ax1, cax] = plt.subplots(1,2, gridspec_kw=dict(width_ratios=[10,1]))
ax1.set_xlabel( "Time (s)" )
ax1.set_ylabel( "Celsius" )
ax2 = ax1.twinx()
ax2.set_ylabel( "Fahrenheit" )
ax2.set_ylim( [temp_f.min(), temp_f.max()] )
img = ax1.imshow( zi, vmin=height.min(), vmax=height.max(), origin='lower',
extent=[time.min(), time.max(), temp.min(), temp.max()],
aspect='auto', cmap='YlOrRd')
plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1, cax=cax)
plt.show()
You get:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With