Skip to content Skip to sidebar Skip to footer

Two Colorbars On Image Grid In Matplotlib

I would like to have the following layout in matplotlib: Image 1a Image 1b Image 2a Image 2b Colorbar a Colorbar b The Colorbar a is for Image set a, and the Colobar b is for

Solution 1:

For future reference, it helps to have a full working example, so that someone could copy and paste your code and reproduce your issue directly. For example, I can see you've imported ImageGrid, but a full import statement would help with this, as would creating fake data sets for data1a, data1b, etc.

Also, it looks like you have a (1,6) where you should have (1,4) in your statement above: grid = ImageGrid(fig, 111, (1,4), aspect=False, share_all=False), though this is not the solution to your problem.

When I want two or more color bars, my approach is typically to use get_position() on an axis, which returns the coordinates for the axis corners as attributes x0,y0,x1,y1. From here, I define each colorbar's axis separately and place each precisely where I want it to go. To get this to suit your needs, you'll have to tinker with the details of fig.add_axes([1.01, bbox_ax.y0, 0.02, bbox_ax.y1-bbox_ax.y0]) in the code below. For example, the first two entries 1.01, bbox_ax.y0 mean "place the bottom corner at x=1.01 and y=bbox_ax.y0". The second two entries, 0.02, bbox_ax.y1-bbox_ax.y0 define the horizontal and vertical width of the colorbar axis, respectively. I like the colorbar axes to be flush with the plot axes, so I use bbox_ax.y1-bbox_ax.y0 for the vertical width.

Note that I'm using mp.subplots() instead of ImageGrid(), since I'm not as familiar with the latter, and I don't think it's necessary.

import matplotlib.pyplot as mp
import numpy
import mpl_toolkits.axes_grid1

data1a = numpy.random.rand(100,100)
data1b = numpy.random.rand(100,100)
data2a = numpy.random.rand(100,100)
data2b = numpy.random.rand(100,100)

fig, axes = mp.subplots(1, 4, figsize=(8,2))

im1a = axes[0].pcolormesh(data1a, cmap='magma')
im1b = axes[1].pcolormesh(data1b, cmap='magma')
im2a = axes[2].pcolormesh(data2a, cmap='viridis')
im2b = axes[3].pcolormesh(data2b, cmap='viridis')

fig.tight_layout()

# get bounding box information for the axes (since they're in a line, you only care about the top and bottom)
bbox_ax = axes[0].get_position()

# fig.add_axes() adds the colorbar axes# they're bounded by [x0, y0, x_width, y_width]
cbar_im1a_ax = fig.add_axes([1.01, bbox_ax.y0, 0.02, bbox_ax.y1-bbox_ax.y0])
cbar_im1a = mp.colorbar(im1a, cax=cbar_im1a_ax)

cbar_im2a_ax = fig.add_axes([1.09, bbox_ax.y0, 0.02, bbox_ax.y1-bbox_ax.y0])
cbar_im1a = mp.colorbar(im2a, cax=cbar_im2a_ax)

This produces the figure below:

enter image description here

You can also do this as a 2x2 grid with slightly different syntax:

fig, axes = mp.subplots(2, 2, figsize=(4,4))

im1a = axes[0,0].pcolormesh(data1a, cmap='magma')
im1b = axes[0,1].pcolormesh(data1b, cmap='magma')
im2a = axes[1,0].pcolormesh(data2a, cmap='viridis')
im2b = axes[1,1].pcolormesh(data2b, cmap='viridis')

fig.tight_layout()

bbox_ax_top = axes[0,1].get_position()
bbox_ax_bottom = axes[1,1].get_position()

cbar_im1a_ax = fig.add_axes([1.01, bbox_ax_top.y0, 0.02, bbox_ax_top.y1-bbox_ax_top.y0])
cbar_im1a = mp.colorbar(im1a, cax=cbar_im1a_ax)

cbar_im2a_ax = fig.add_axes([1.01, bbox_ax_bottom.y0, 0.02, bbox_ax_bottom.y1-bbox_ax_bottom.y0])
cbar_im1a = mp.colorbar(im2a, cax=cbar_im2a_ax)

Which produces this figure:

enter image description here

Solution 2:

Using pcolormesh, which by default is plotted to axes with automatic aspect, does not require any special treatment to create colorbars.

The easiest way of doing so is to use a grid with unequal column width. The rest comes automatically.

import matplotlib.pyplotas plt
import numpy as np

fig, axes = plt.subplots(ncols=6,figsize=(7,2.2), 
                  gridspec_kw={"width_ratios":[1,1,1,1, 0.08,0.08]})
fig.subplots_adjust(wspace=0.6)

im0  = axes[0].pcolormesh(np.random.rand(11,11), vmin=0, vmax=1, cmap="RdBu")
im1  = axes[1].pcolormesh(np.random.rand(11,11), vmin=0, vmax=1, cmap="RdBu")
im2  = axes[2].pcolormesh(np.random.rand(11,11), vmin=0, vmax=1)
im3  = axes[3].pcolormesh(np.random.rand(11,11), vmin=0, vmax=1)

axes[0].set_ylabel("y label")

fig.colorbar(im0, cax=axes[4])
fig.colorbar(im2, cax=axes[5])

plt.show()

enter image description here

Post a Comment for "Two Colorbars On Image Grid In Matplotlib"