2

I know I can use update to adjust the parameters of a GridSpec instance in a matplotlib figure, allowing to arrange multiple gridspec's in a single figure. Much as in this example taken from the matplotlib doc

gs1 = gridspec.GridSpec(3, 3)
gs1.update(left=0.05, right=0.48, wspace=0.05)
ax1 = plt.subplot(gs1[:-1, :])
ax2 = plt.subplot(gs1[-1, :-1])
ax3 = plt.subplot(gs1[-1, -1])

gs2 = gridspec.GridSpec(3, 3)
gs2.update(left=0.55, right=0.98, hspace=0.05)
ax4 = plt.subplot(gs2[:, :-1])
ax5 = plt.subplot(gs2[:-1, -1])
ax6 = plt.subplot(gs2[-1, -1])

But how can I give both gs1 and gs2 their own common title? Using suptitle I only get a common title for the whole figure at once.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158

2 Answers2

5

Way too late, but just found this thread when searching for the exact same thing, so just leaving this for anyone stumbling across it.

I think @pathoren's Alternative 4) is the way to go, but you can reuse the existing gridspec to create your ghost axis such that it exactly matches the existing ones:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure()
gs1 = gridspec.GridSpec(3, 3)
gs1.update(left=0.05, right=0.48, wspace=0.05)
ax1 = fig.add_subplot(gs1[:-1, :])
ax2 = fig.add_subplot(gs1[-1, :-1])
ax3 = fig.add_subplot(gs1[-1, -1])

gs2 = gridspec.GridSpec(3, 3)
gs2.update(left=0.55, right=0.98, hspace=0.05)
ax4 = fig.add_subplot(gs2[:, :-1])
ax5 = fig.add_subplot(gs2[:-1, -1])
ax6 = fig.add_subplot(gs2[-1, -1])

# Add ghost axes and titles on gs1 and gs2
ax_left = fig.add_subplot(gs1[:])
ax_left.axis('off')
ax_left.set_title('Left title')

ax_right = fig.add_subplot(gs2[:])
ax_right.axis('off')
ax_right.set_title('Right title')

plt.show()

Resulting layout:

Resulting layout

Ryan M
  • 18,333
  • 31
  • 67
  • 74
3

I can think of four ways, all quite ugly. I do not know if there are any automatic way of setting such things.

The four ugly ways are:

1) Set the title to the "top" axis-object in each group with ax.set_title() (in your case ax1 and ax4). It works great on the left group, but horrible for the right group...

2) Set one title with fig.suptitle, but make a lot of spaces inside the title, and use horizontalalignment='center'.

3) Set a text-object manually for each title... (not in the example below, but just look at matplotlib.text)

4) Create ghost axes, hide everything on them and just use them to set their title...

Below is some example code

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure()
gs1 = gridspec.GridSpec(3, 3)
gs1.update(left=0.05, right=0.48, wspace=0.05)
ax1 = fig.add_subplot(gs1[:-1, :])
ax2 = fig.add_subplot(gs1[-1, :-1])
ax3 = fig.add_subplot(gs1[-1, -1])
ax1.set_title('Left group title')  # Alternative 1)

gs2 = gridspec.GridSpec(3, 3)
gs2.update(left=0.55, right=0.98, hspace=0.05)
ax4 = fig.add_subplot(gs2[:, :-1])
ax5 = fig.add_subplot(gs2[:-1, -1])
ax6 = fig.add_subplot(gs2[-1, -1])
ax4.set_title('Right group title')  # Alternative 1)
# Alternative 2. Note the many white-spaces
fig.suptitle('figure title left                                                   figure title right', horizontalalignment='center')

# Alternative 4)
rect_left = 0, 0, 0.5, 0.8  # lower, left, width, height (I use a lower height than 1.0, to place the title more visible)
rect_right = 0.5, 0, 0.5, 0.8
ax_left = fig.add_axes(rect_left)
ax_right = fig.add_axes(rect_right)
ax_left.set_xticks([])
ax_left.set_yticks([])
ax_left.spines['right'].set_visible(False)
ax_left.spines['top'].set_visible(False)
ax_left.spines['bottom'].set_visible(False)
ax_left.spines['left'].set_visible(False)
ax_left.set_axis_bgcolor('none')
ax_right.set_xticks([])
ax_right.set_yticks([])
ax_right.spines['right'].set_visible(False)
ax_right.spines['top'].set_visible(False)
ax_right.spines['bottom'].set_visible(False)
ax_right.spines['left'].set_visible(False)
ax_right.set_axis_bgcolor('none')
ax_left.set_title('Ghost left title')
ax_right.set_title('Ghost right title')

plt.show()

enter image description here

pathoren
  • 1,634
  • 2
  • 14
  • 22
  • 1
    Thx for your ideas. I like the ghost solution best. Still, it would be logical if the `GridSpec` instance actually had the properties of a sort of "subfigure" allowing to set a `suptitle` per `GridSpec` instance. Wouldnt you agree ? – Mathias Vanwolleghem Oct 13 '16 at 17:28
  • I do not know if it already exist or not. However making such a thing as general as it has to be seem extremely tricky and I doubt that has been done. My best tip for applications like these is to just do it manually, as I showed :) – pathoren Oct 13 '16 at 19:13
  • It looks like alternative 2 isn't complete – MERose Sep 28 '20 at 21:19