I'm currently working on plotting data using plt.imshow() and plt.colorbar() in Python.
class MidpointNormalize(mcolors.Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
mcolors.Normalize.__init__(self, vmin, vmax, clip)
def __call__(self, value, clip=None):
v_ext = np.max( [ np.abs(self.vmin), np.abs(self.vmax) ] )
x, y = [-v_ext, self.midpoint, v_ext], [0, 0.5, 1]
return np.ma.masked_array(np.interp(value, x, y))
plt.figure()
plt.imshow(data, aspect='auto', norm=MidpointNormalize(vmin=vmin, vmax=vmax, midpoint=0), cmap='RdBu_r')
plt.colorbar()
for (x,y), value in np.ndenumerate(data.T):
plt.text(x, y, f'{value}', ha='center',va='center', c= 'w' if value>0.5*vmax else 'k')
In the resulting plot, I notice that although the highest value in the data is 8.29, the corresponding color on the colorbar is labeled as "10". I'm curious why this discrepancy occurs and how I might go about correcting it. Any insights or suggestions would be greatly appreciated. Thank you!
I experimented with adding a mappable for the colorbar and using set_clim(). Additionally, I attempted to manually set the ticks, but given that the values vary for different datasets, I'm seeking a dynamic method to generate these ticks accurately.
Thank you JohanC for your quick answer. To answer your first question: vmax and vmin are extracted from the data itself:
vmin, vmax = data.min(), data.max()
I tried it using seaborn as you suggested but I'm still not getting the colorbar as needed.
Zero is displayed in the middle of the colorbar, although since the values range from -1.9 to 8.3 it should be closer to the bottom end. In addition, the value -1.9 and 8.3 share the same level of darkness, but -1.9 should be as light as +1.9.
Thank you very much for further help!
