More than one color bar on plot

38 Views Asked by At

I am trying to plot three plots on one figure. Left two are just regular plots, but the top right one needs to be a correlation matrix with three additional colorbars, but I can't seem to get the sizes of colorbars right.

I tried with gridspec and subgridspecs like this:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib.colors import ListedColormap
import numpy as np

np.random.seed(123941)
data = np.random.rand(20, 20)

cmap_bm_type = ListedColormap(['mediumseagreen', 'greenyellow', 'darkorchid', 'plum'])

fig = plt.figure(figsize=[12, 8])
gs = gridspec.GridSpec(2, 2, figure=fig)
ax1 = fig.add_subplot(gs[0])
sgs = gs[1].subgridspec(2, 3, height_ratios=[0.95, 0.05],
                        width_ratios=[0.15, 0.70, 0.15],
                        wspace=0.05)
ax2 = fig.add_subplot(sgs[1])
ax2.imshow(data)
ax2.axis('off')
cbar_left = fig.add_subplot(sgs[0])
cbar_bottom = fig.add_subplot(sgs[2])
cbar_right = fig.add_subplot(sgs[4])
ax3 = fig.add_subplot(gs[2])

plt.show()

But all I can get is this

Can anybody help me how I could make ´cbar_bottom´ the same width 'visually' as the ´ax2´ ?

1

There are 1 best solutions below

0
Jaka Kovše On

After quite a while I finally found a solution. I helped myself with this example from matplotlib docs.

Here is an example:

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

np.random.seed(123941)
data = np.random.rand(20, 20)

cmap_bm_type = ListedColormap(['mediumseagreen', 'greenyellow', 'darkorchid', 'plum'])
bm_types = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]])
bm_types = np.tile(bm_types, (12, 1))
fig = plt.figure(figsize=[12, 8])
gs = gridspec.GridSpec(2, 2, figure=fig)
ax1 = fig.add_subplot(gs[0])
sgs = gs[1].subgridspec(2, 5, height_ratios=[0.95, 0.05],
                        width_ratios=[0.13, 0.04, 0.66, 0.04, 0.13],
                        wspace=0.1, hspace=0.05)

ax2 = fig.add_subplot( 222 )
ax2.set_aspect(1.)
im = ax2.imshow( data, cmap='RdBu_r', vmin=-1, vmax=1, origin="lower" )
divider_ax2 = make_axes_locatable(ax2)
ax2.set_title( "Biomarker correlation matrix" )
ax2.tick_params(bottom=False, left=False, labelbottom=False, labelleft=False)

# add colorbars on lef, bottom and right
divider = make_axes_locatable(ax2)

cbar_r = divider.append_axes("right", .2, pad=.05)
trans = cbar_r.get_yaxis_transform()
cbar_r_vals = np.linspace(-1, 1, 204, endpoint=True)
cbar_r_vals = np.tile(cbar_r_vals, (8, 1))
cbar_r.imshow( cbar_r_vals.T, cmap='RdBu')
cbar_r.tick_params(bottom=False, left=False, right=True,
                   labelbottom=False, labelleft=False)
cbar_b = divider.append_axes("bottom", .2, pad=.05)
cbar_b.imshow( bm_types, vmax=4, vmin=0, interpolation="nearest", cmap=cmap_bm_type )

cbar_l = divider.append_axes("left", .2, pad=.05)
cbar_l.imshow( np.flip(bm_types.T) , vmax=4, vmin=0, interpolation="nearest", cmap=cmap_bm_type)

ax3 = fig.add_subplot(gs[2])

plt.show()

I hope this helps someone else too.