How can colour bar scales be shared amongst subplots? - python

I have the following code:
f, ax = plt.subplots(1,2, figsize=(20,20))
divider = make_axes_locatable(ax[0])
cax = divider.append_axes("right", size="5%", pad=0.1)
#level_geo.boundary.plot(ax=ax[0], color='black')
level_geo.plot(ax=ax[0], cmap='viridis', column='dem_2001', legend=True, cax=cax)
divider = make_axes_locatable(ax[1])
cax = divider.append_axes("right", size="5%", pad=0.1)
#level_geo.boundary.plot(ax=ax[1], color='black')
level_geo.plot(ax=ax[1], cmap='viridis', column='dem_2030', legend=True, cax=cax)
plt.show()
I am wondering how I share the colour bars so that there is just one bar with a scale relevant to both plots?

If you want just a linear color map, you can just pass vmin and vmax to both plots.
f, ax = plt.subplots(1,2, figsize=(20,20))
divider = make_axes_locatable(ax[0])
cax = divider.append_axes("right", size="5%", pad=0.1)
#level_geo.boundary.plot(ax=ax[0], color='black')
level_geo.plot(ax=ax[0], cmap='viridis', column='dem_2001', legend=True, cax=cax, vmin=0, vmax=1)
divider = make_axes_locatable(ax[1])
cax = divider.append_axes("right", size="5%", pad=0.1)
#level_geo.boundary.plot(ax=ax[1], color='black')
level_geo.plot(ax=ax[1], cmap='viridis', column='dem_2030', legend=True, cax=cax, vmin=0, vmax=1)
plt.show()
Or, better, use min and max retrieved from the data (e.g. level_geo['dem_2030'].min())

Related

Color bar limits doesn't follow the data limits

I am trying to make plot with two 2d histograms. And i need them both to have a colorbar. But, i was able to plot the colobar at the lateral of one of these histograms, but as can see in the image below, the limits of the color bar doesn't reflect the limits of the histogram. The bin with higher number of events should have around 830 events. (ps: i had set the limits of the colorbar by hand using im2.set_clim(vmin=0, vmax=10000), but before that it was from -20 to 20) .
The code i used to plotis something like:
plt.set_cmap('gnuplot')
fig = plt.figure()
fig.set_size_inches(10, 10)
ax = fig.add_subplot(121,aspect='equal')
ax2 = fig.add_subplot(122, aspect='equal')
ax2.hist2d(data2,datay2,bins=(100,100), rasterized=True,range=np.array([(-7.9, 7.9), (-7.9, 7.9)]))
ax2.set_title('HMC with L=5.0 and t=1.5 ', size= 16, fontname='Comic Sans MS')
ax2.tick_params(axis='both', which='major', labelsize=10)
ax2.tick_params(axis='both', which='minor', labelsize=10)
ax.hist2d(data,datay,bins=(100,100), rasterized=True,range=np.array([(-7.9, 7.9), (-7.9, 7.9)]))
ax.set_title('NUTS ', size= 16, fontname='Comic Sans MS')
ax.tick_params(axis='both', which='major', labelsize=10)
ax.tick_params(axis='both', which='minor', labelsize=10)
#down here i am trying to plot the color map
im2 = ax2.imshow(chain,cmap ='gnuplot' ,interpolation='None')
divider = make_axes_locatable(ax2)
cax = divider.append_axes('right', size='5%', pad=0.05)
im2.set_clim(vmin=0, vmax=10000)
fig.colorbar(im2, cax=cax, orientation='vertical');
fig.text(0.5, 0.02, 'Generalized Coordinate', ha='center', size = 16)
fig.text(0.07, 0.5, 'Generalized Momenta', va='center', rotation='vertical',size = 16)
plt.savefig('2DHMCpog.pdf')
plt.savefig('2DHMCpog.png')
plt.show()
From this answer, you can use the return values of hist2d to set a local color bar. E.g.:
h = ax2.hist2d(data2,datay2,bins=(100,100), …
fig.colorbar(h[3], ax=ax2)
ax2.set_title('HMC with …
Do the same for the second histogram.

How to set some space between the colorbar and the image

I would like to set some space between the image and the colorbar, I have tried the pad but do nothing, so...
This is the image I have:
and this is the code:
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.colors import LogNorm
from matplotlib.ticker import LogLocator
from matplotlib import rcParams
rcParams['font.size']=35
x = np.arange(0,16,1)
yx= np.linspace(-50,0,38)
mx = np.random.rand(15,38)
m2 = np.linspace(0,6,38)
fig, ax = plt.subplots(figsize=(40,30))
divider = make_axes_locatable(ax)
cax = divider.append_axes('right', size='5%', pad=2)
im = ax.pcolor(x,yx,mx.T,norm=LogNorm(0.1, 100),cmap= 'jet')
cbar = fig.colorbar(im,pad = 2,cax=cax, orientation='vertical')
cbar.ax.yaxis.set_major_locator(LogLocator()) # <- Why? See above.
cbar.ax.set_ylabel('Resistividade \u03C1 [ohm.m]', rotation=270)
ax2=ax.twiny()
ax2.plot(m2,yx,'k--',linewidth=10)
#ax2.set_xlim([0,60])
ax2.set_xlabel('Resistividade \u03C1 [ohm.m]')
ax.set_xlabel('Aquisição')
ax.set_ylabel('Profundidade [m]')
#fig.tight_layout()
plt.savefig('mrec_1'+'.png',bbox_inches = "tight", format='png', dpi=300)
plt.show()
The secondary axes occupies all of the space in the figure that is meant for axes. Therefore, no matter what padding you give to the colorbar of ax, it wont affect ax2.
A hacky-ish solution would be to also spit your secondary axes exactly the same as the primary axes, and then delete the axes where the second colorbar goes:
fig, ax = plt.subplots(figsize=(10, 8))
pad = 0.2 # change the padding. Will affect both axes
im = ax.pcolor(x, yx, mx.T, norm=LogNorm(0.1, 100), cmap='jet')
divider = make_axes_locatable(ax)
cax = divider.append_axes('right', size='5%', pad=pad)
ax2 = ax.twiny()
ax2.plot(m2, yx, 'k--', linewidth=10)
ax2.set_xlim([0, 60])
ax2.set_xlabel('Resistividade \u03C1 [ohm.m]')
ax.set_xlabel('Aquisição')
ax.set_ylabel('Profundidade [m]')
cbar = fig.colorbar(im,pad = 2,cax=cax, orientation='vertical')
cbar.ax.yaxis.set_major_locator(LogLocator())
cbar.ax.set_ylabel('Resistividade \u03C1 [ohm.m]', rotation=270)
secondary_divider = make_axes_locatable(ax2) # divide second axes
redundant_cax = secondary_divider.append_axes('right', size='5%', pad=pad)
redundant_cax.remove() # delete the second (empty) colorbar
plt.show()

How to make a heatmap contour plot using three 2D arrays?

So I've seen examples where you have two 1D arrays and use a meshgrid then just use the two values from that and your z array to create the contour. But I have 3 inherently 2D arrays that I need for a contour, but so far this is what is being displayed. Any ideas? (Ignore the dummy variable names) Photo and code as listed:enter image description here
fig = plt.figure(figsize=(16,16))
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
contourOne = ax1.contourf(data,data2, np.log(data3))
ax1.set_title("title")
ax1.set_xlabel("idk")
ax1.set_ylabel("idk")
divider = make_axes_locatable(ax1)
cax = divider.append_axes('right', size='5%', pad=0.05)
fig.colorbar(contourOne, cax=cax, orientation='vertical')
contourTwo = ax2.contourf(data4,data5, np.log(data6))
ax2.set_title("title")
ax2.set_xlabel("idk")
ax2.set_ylabel("idk")
divider = make_axes_locatable(ax2)
cax = divider.append_axes('right', size='5%', pad=0.05)
fig.colorbar(contourTwo, cax=cax, orientation='vertical')
#Set graph spacing and show graphs
plt.subplots_adjust(wspace=0.4,hspace=0.5)
plt.show()

Seaborn Heatmap Behavior

Consider this code:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, cbar=None, cmap="Blues", linewidths=1, linecolor='black')
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, cmap="Blues", linewidths=1, linecolor='black')
It outputs:
Why does adding the argument cbar=None change the result of the outcome?
It is the default behavior by cbar, some kind of bug.
Turn off cbar:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4, 4)), ax=ax, cmap='Blues', linewidths=1, linecolor='black', cbar=False, vmin=0, vmax=2)
Turn on cbar:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, cmap='Blues', linewidths=1, linecolor='black', cbar=True, vmin=0, vmax=2)
As showed by #Alpha, cbar value should be boolean as it can be seen in the documentation
cbar : boolean, optional
Whether to draw a colorbar.
For both figures to have the same size, you can use:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, linewidths=1, linecolor='black', cmap="Blues",)
cbar = ax.collections[0].colorbar
cbar.remove()
plt.show()
and ...
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, linewidths=1, linecolor='black', cmap="Blues",)
cbar = ax.collections[0].colorbar
#cbar.remove()
plt.show()

Python Fix colorbar in plot

I am trying to get rid of the overlap of the images and colorbar values on the right side, but nothing seems to work. I have tried the 'tight' command and to shrink the size of the color bar text. The former does not help and the latter does not seem to work at all. (Is this possible?) I need a way to read these numbers, it does not really matter how. (As long as they don't overlap)
gs = gridspec.GridSpec(1, 2)
gs0 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs[0])
gs1 = gridspec.GridSpecFromSubplotSpec(2, 2, subplot_spec=gs[1])
fig = plt.figure()
ax = fig.add_subplot(gs0[0, 0])
plt.imshow(getpoly(seg1),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[0, 1])
plt.imshow(getpoly(seg2),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[0, 2])
plt.imshow(getpoly(seg3),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[1, 0])
plt.imshow(getpoly(seg4),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[1, 1])
plt.imshow(getpoly(seg5),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[1, 2])
plt.imshow(getpoly(seg6),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[2, 1])
plt.imshow(getpoly(seg7),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[2, 2])
plt.imshow(getpoly(seg8),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs0[2, 0])
plt.imshow(getpoly(seg9),origin="lower")
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs1[0, 0])
plt.imshow(h1,origin="lower")
plt.colorbar(fraction=0.046, pad=0.04)
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs1[0, 1])
plt.imshow(h2,origin="lower")
plt.colorbar(fraction=0.046, pad=0.04)
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs1[1, 0])
plt.imshow(getpoly(h2),origin="lower")
plt.colorbar(fraction=0.046, pad=0.04)
ax.set_xticks([]); ax.set_yticks([])
ax = fig.add_subplot(gs1[1, 1])
plt.imshow(h1-getpoly(h2),origin="lower")
plt.colorbar(fraction=0.046, pad=0.04)
ax.set_xticks([]); ax.set_yticks([])
plt.tight_layout()
You may look at the colorbar-whose-height-or-width-in-sync-with-the-master-axes-example.
The idea is to cut a bit of the axes using mpl_toolkits.axes_grid1.make_axes_locatable and create a new axes into which the colorbar can be placed, using fig.colorbar(im, cax=cax).
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import make_axes_locatable
gs = gridspec.GridSpec(1, 2)
gs0 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs[0])
gs1 = gridspec.GridSpecFromSubplotSpec(2, 2, subplot_spec=gs[1])
fig = plt.figure()
for i in range(9):
ax = fig.add_subplot(gs0[i//3, i%3])
ax.imshow(np.random.rand(4,4))
ax.set_xticks([]); ax.set_yticks([])
for i in range(4):
ax = fig.add_subplot(gs1[i//2, i%2])
im = ax.imshow(np.random.rand(4,4))
ax.set_xticks([]); ax.set_yticks([])
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
fig.colorbar(im, ax=ax, cax=cax)
plt.show()
I've found it easier to add the colorbar separately
cax = fig.add_axes([0.125, 0.925, 0.775, 0.0725])
#the numbers in fig.add_axes are all percentages
norm = mpl.colors.Normalize(vmin=low_val, vmax=high_val)
mpl.colorbar.ColorbarBase(cax, cmap='rainbow', norm=norm, orientation='horizontal')
fig.add_axes details

Categories

Resources