How to adjust gridspec spacing

Question:

I have a matplotlib plot with 3×2 subplots. I want no spacing between the columns (achieved), and no spacing between the first (a, b) and the second row (c, d). However, the third row (e, f) should be well separated from the second, as it has different data.

Additionally, I am placing titles for the subplots in the third row to help the reader understand the contents. Unfortunately the labels touch in the middle. I would like to add some spacing, for example a non-breaking space.

I am not fixed on using gridspec, I just used it because I am a bit familiar with it.
The height and width of the entire plot are fixed though.

Currently my figure looks like this:

not beautiful figure

Generated with the following code:

import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms

fig_width = 150/25.4
fig_height = 100/25.4
fig = plt.figure(figsize=(fig_width, fig_height))
gs = fig.add_gridspec(3, 2, wspace=0, hspace=0.6, height_ratios=[3,3,2])
(a, b, c) = gs.subplots(sharey='row')
b[0].set_xlabel("x")
b[1].set_xlabel("x")
c[0].set_xlabel("t")
c[1].set_xlabel("t")
trans = mtransforms.ScaledTranslation(10/72, -5/72, fig.dpi_scale_trans)
a[0].text(0.0, 1.0, "a", transform=a[0].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
a[1].text(0.0, 1.0, "b", transform=a[1].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
b[0].text(0.0, 1.0, "c", transform=b[0].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
b[1].text(0.0, 1.0, "d", transform=b[1].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
c[0].text(0.0, 1.0, "e", transform=c[0].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
c[1].text(0.0, 1.0, "f", transform=c[1].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
c[0].set_title("left", loc="left")
c[0].set_title("right", loc="right")
c[1].set_title("left", loc="left")
c[1].set_title("right", loc="right")
fig.tight_layout()
plt.show()
Asked By: laolux

||

Answers:

You could use a subgridspec.
As for the titles – you could either append/prepend a space to the title string or adjust the horizontal positions as shown below.

import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms

fig_width = 150/25.4
fig_height = 100/25.4
fig = plt.figure(figsize=(fig_width, fig_height))

gs = fig.add_gridspec(2, 1, hspace=0.6, height_ratios=[6,2])

gs0 = gs[0].subgridspec(2, 2, wspace=0, hspace=0)
gs1 = gs[1].subgridspec(1, 2, wspace=0)

a, b = gs0.subplots(sharey='row', sharex='col')
c = gs1.subplots(sharey='row')

b[0].set_xlabel("x")
b[1].set_xlabel("x")
c[0].set_xlabel("t")
c[1].set_xlabel("t")
trans = mtransforms.ScaledTranslation(10/72, -5/72, fig.dpi_scale_trans)
a[0].text(0.0, 1.0, "a", transform=a[0].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
a[1].text(0.0, 1.0, "b", transform=a[1].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
b[0].text(0.0, 1.0, "c", transform=b[0].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
b[1].text(0.0, 1.0, "d", transform=b[1].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
c[0].text(0.0, 1.0, "e", transform=c[0].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
c[1].text(0.0, 1.0, "f", transform=c[1].transAxes + trans,
        fontsize='medium', verticalalignment='top', fontfamily='serif',
        bbox=dict(facecolor='1.0', edgecolor='none', pad=3.0))
c[0].set_title("left", loc="left")
c[0].set_title("right", loc="right")
c[1].set_title("left", loc="left")
c[1].set_title("right", loc="right")
c[0]._right_title.set_position((0.99, 1))
c[1]._left_title.set_position((0.01, 1))

enter image description here

Answered By: Stef