Using a color bar with a second y-axis
I am trying to add a colorbar to a chart with a secondary y-axis. Below is a minimal example of my difficulties. The trouble is, I can't add a colorbar to the AxesSubplot and add it directly, as plt.colorbar is placing it on top of my plot - see how it overlaps the right-most y-axis. How can I fix this? Greetings.
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()
source to share
See the location of the color bar .
You can manually specify the location of the color bar:
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)
source to share
plt.colorbar
does a good job for simple single axis plots. With more complex settings, it can get confusing. Therefore, it is better to manually adjust the axes for the color bar. You can use the function for this subplots
. By supplying gridspec_kw
, you can specify the base GridSpec
object how you want to specify the width:
fig, [ax1, cax] = plt.subplots(1,2, gridspec_kw=dict(width_ratios=[10,1]))
when creating a color bar, you want to specify the axes to be used to create the color bar:
plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1, cax=cax)
So with the complete 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:
source to share