Search code examples
pythonmatplotlibcolorbar

Multiple panels with a common colorbar using divider.append_axes option


I am trying to add one colorbar common to 4 panels. The answers I found here were good but unfortunately not entirely useful to me. The main challenge I was facing in these methods was the adjustment of colorbar width, height, distance from the panels and the spacing among the panels themselves.

Given below is the code I am now using. In the current output, the figure size, placement of panels, spacing and bar width is exactly as I want except for the bar height and the top right panel. Can anyone help me on how to make the bar as high as the top panel's upper edge and correct the top right panel placement?

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

arr = np.random.random((4,10,10))

fig, axes = plt.subplots(nrows=2, ncols=2, sharex=True,sharey=True, figsize=(10.1,10))
fig.subplots_adjust(left=0.04, bottom=0.1, right=0.96, top=0.9, wspace=-0.2, hspace=0.01)

for i in range(2):
    for j in range(2):
        c = axes[i,j].imshow(arr[2*i+j,:,:].T, cmap='cool',aspect='equal',origin='lower')
        axes[i,j].tick_params(axis='both', which='major', length=5, width=1, labelsize=20,direction='in')
        axes[i,j].tick_params(axis='both', which='minor', length=3, width=1,direction='in')
        axes[i,j].minorticks_on()
        axes[i,j].yaxis.set_ticks_position('both')
        axes[i,j].xaxis.set_ticks_position('both')
        axes[i,j].set_aspect(1.0/axes[i,j].get_data_ratio(), adjustable='box')


divider = make_axes_locatable(axes[1,1])
cax = divider.append_axes("right", size="5%", pad=0.05)
cb=plt.colorbar(c,cax)
cb.set_label(r'$x/y$',fontsize=16)
cb.ax.tick_params(labelsize=16)

plt.savefig('plot.png')

See output plot here


Solution

  • You have different options. I suggest using AxesGrid

    enter image description here

    import matplotlib.pyplot as plt
    from mpl_toolkits.axes_grid1 import AxesGrid
    
    fig = plt.figure(figsize=(7, 6))
    grid = AxesGrid(fig, 111, nrows_ncols=(2,2), axes_pad=0.25,
                    cbar_size="6%", cbar_location="right", cbar_mode="single")
    images = [ax.imshow([[1, 2], [3, 4]]) for ax in grid.axes_all]
    cbar = plt.colorbar(images[0], cax=grid.cbar_axes[0])
    plt.show()