0

I want to create a figure containing multiple subplots, with a title per row, and a common colorbar for every plot in the figure. However, I am unable to find how this is done, as I keep on getting the error 'Unable to create a colorbar axes as not all parents share the same figure.' and I am struggling to resolve this issue.

Does someone know how this can be done? Below is a minimal example that should generate the error.

import numpy as np
import matplotlib.pyplot as plt

datarow1 = [np.random.random((10, 10)), np.random.random((10, 10))]
datarow2 = [np.random.random((10, 10)), np.random.random((10, 10))]

fig = plt.figure(constrained_layout=True)
fig.suptitle('Main title', weight='bold', fontsize=20)
subfigs = fig.subfigures(2, 1)

subfigs[0].suptitle('Title row 1')
axesrow1 = subfigs[0].subplots(nrows=1, ncols=2)
axesrow1[0].imshow(datarow1[0], vmin=0, vmax=1, cmap='viridis')
axesrow1[1].imshow(datarow1[1], vmin=0, vmax=1, cmap='viridis')

subfigs[1].suptitle('Title row 2')
axesrow2 = subfigs[1].subplots(nrows=1, ncols=2)
axesrow2[0].imshow(datarow2[0], vmin=0, vmax=1, cmap='viridis')
axesrow2[1].imshow(datarow2[1], vmin=0, vmax=1, cmap='viridis')

fig.colorbar(plt.cm.ScalarMappable(cmap='viridis', norm=plt.Normalize(0, 1)), orientation='vertical', ax=fig.get_axes())

plt.show()

enter image description here

rvdaele
  • 114
  • 10

1 Answers1

0

I found the following solution using gridspec (adapted from Row titles for matplotlib subplot)

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

datarow1 = [np.random.random((10, 10)), np.random.random((10, 10))]
datarow2 = [np.random.random((10, 10)), np.random.random((10, 10))]

fig = plt.figure(figsize=(9, 9), constrained_layout=True)
fig.suptitle('Main title', weight='bold', fontsize=20)
grid = plt.GridSpec(2, 1)

fake = fig.add_subplot(grid[0])
fake.set_title('Title row 1')
fake.set_axis_off()
gs = gridspec.GridSpecFromSubplotSpec(1, 2, subplot_spec=grid[0])
ax = fig.add_subplot(gs[0])
ax.imshow(datarow1[0], vmin=0, vmax=1, cmap='viridis')
ax = fig.add_subplot(gs[1])
ax.imshow(datarow1[1], vmin=0, vmax=1, cmap='viridis')

fake = fig.add_subplot(grid[1])
fake.set_title('Title row 2')
fake.set_axis_off()
gs = gridspec.GridSpecFromSubplotSpec(1, 2, subplot_spec=grid[1])
ax = fig.add_subplot(gs[0])
ax.imshow(datarow2[0], vmin=0, vmax=1, cmap='viridis')
ax = fig.add_subplot(gs[1])
ax.imshow(datarow2[1], vmin=0, vmax=1, cmap='viridis')

fig.patch.set_facecolor('white')
fig.colorbar(plt.cm.ScalarMappable(cmap='viridis', norm=plt.Normalize(0, 1)), orientation='vertical', ax=fig.get_axes())

plt.show()

enter image description here

rvdaele
  • 114
  • 10