Question: In matplotlib, Is it possible to set a a separate title for each row of subplots in addition to the title set for the entire figure and the title set for each individual plot? This would correspond to the orange text in the figure below.
![enter image description here](https://i.stack.imgur.com/K7950.png)

If not, how would you get around this problem? Create a separate column of empty subplots to the left and fill them with the orange text?

I am aware that it is possible to manually position each single title using `text()` or `annotate()`, but that usually requires a lot of tweaking and I have many subplots. Is there a smoother solution?

Answer: 
New in matplotlib 3.4.0
-----------------------

Row titles can now be implemented as **subfigure suptitles**:

> 
> The new subfigure feature allows creating virtual figures within figures with localized artists (e.g., colorbars and **suptitles**) that **only pertain to each subfigure**.
> 
> 
> See [how to plot subfigures](https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subfigures.html) for further details.
> 
> 
> 

---

How to reproduce OP's reference figure:

* ### Either [`Figure.subfigures`](https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure.subfigures) (most straightforward)

Create 3x1 `fig.subfigures` where each `subfig` gets its own 1x3 `subfig.subplots` and `subfig.suptitle`:

```py
fig = plt.figure(constrained_layout=True)
fig.suptitle('Figure title')

# create 3x1 subfigs
subfigs = fig.subfigures(nrows=3, ncols=1)
for row, subfig in enumerate(subfigs):
    subfig.suptitle(f'Subfigure title {row}')

    # create 1x3 subplots per subfig
    axs = subfig.subplots(nrows=1, ncols=3)
    for col, ax in enumerate(axs):
        ax.plot()
        ax.set_title(f'Plot title {col}')

```
* ### Or [`Figure.add_subfigure`](https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure.add_subfigure) (onto existing `subplots`)

If you already have 3x1 `plt.subplots`, then `add_subfigure` into the underlying `gridspec`. Again each `subfig` will get its own 1x3 `subfig.subplots` and `subfig.suptitle`:

```py
# create 3x1 subplots
fig, axs = plt.subplots(nrows=3, ncols=1, constrained_layout=True)
fig.suptitle('Figure title')

# clear subplots
for ax in axs:
    ax.remove()

# add subfigure per subplot
gridspec = axs[0].get_subplotspec().get_gridspec()
subfigs = [fig.add_subfigure(gs) for gs in gridspec]

for row, subfig in enumerate(subfigs):
    subfig.suptitle(f'Subfigure title {row}')

    # create 1x3 subplots per subfig
    axs = subfig.subplots(nrows=1, ncols=3)
    for col, ax in enumerate(axs):
        ax.plot()
        ax.set_title(f'Plot title {col}')

```

---

Output of either example (after some styling):

[![](https://i.stack.imgur.com/on9Rq.png)](https://i.stack.imgur.com/on9Rq.png)
Another easy cheat is to give the title of the middle column as `subplot row XX\n\nPlot title No.YY`