|
3 | 3 | Labelling subplots |
4 | 4 | ================== |
5 | 5 |
|
6 | | -Labelling subplots is relatively straightforward, and varies, |
7 | | -so Matplotlib does not have a general method for doing this. |
| 6 | +Labelling subplots is relatively straightforward, and varies, so Matplotlib |
| 7 | +does not have a general method for doing this. |
8 | 8 |
|
9 | | -Simplest is putting the label inside the axes. Note, here |
10 | | -we use `.pyplot.subplot_mosaic`, and use the subplot labels |
11 | | -as keys for the subplots, which is a nice convenience. However, |
12 | | -the same method works with `.pyplot.subplots` or keys that are |
13 | | -different than what you want to label the subplot with. |
| 9 | +We showcase two methods to position text at a given physical offset (in |
| 10 | +fontsize units or in points) away from a corner of the Axes: one using |
| 11 | +`~.Axes.annotate`, and one using `.ScaledTranslation`. |
| 12 | +
|
| 13 | +For convenience, this example uses `.pyplot.subplot_mosaic` and subplot |
| 14 | +labels as keys for the subplots. However, the approach also works with |
| 15 | +`.pyplot.subplots` or keys that are different than what you want to label the |
| 16 | +subplot with. |
14 | 17 | """ |
15 | 18 |
|
16 | 19 | import matplotlib.pyplot as plt |
17 | 20 |
|
18 | | -import matplotlib.transforms as mtransforms |
| 21 | +from matplotlib.transforms import ScaledTranslation |
19 | 22 |
|
| 23 | +# %% |
20 | 24 | fig, axs = plt.subplot_mosaic([['a)', 'c)'], ['b)', 'c)'], ['d)', 'd)']], |
21 | 25 | layout='constrained') |
22 | | - |
23 | 26 | for label, ax in axs.items(): |
24 | | - # label physical distance in and down: |
25 | | - trans = mtransforms.ScaledTranslation(10/72, -5/72, fig.dpi_scale_trans) |
26 | | - ax.text(0.0, 1.0, label, transform=ax.transAxes + trans, |
27 | | - fontsize='medium', verticalalignment='top', fontfamily='serif', |
28 | | - bbox=dict(facecolor='0.7', edgecolor='none', pad=3.0)) |
29 | | - |
30 | | -plt.show() |
| 27 | + # Use Axes.annotate to put the label |
| 28 | + # - at the top left corner (axes fraction (0, 1)), |
| 29 | + # - offset half-a-fontsize right and half-a-fontsize down |
| 30 | + # (offset fontsize (+0.5, -0.5)), |
| 31 | + # i.e. just inside the axes. |
| 32 | + ax.annotate( |
| 33 | + label, |
| 34 | + xy=(0, 1), xycoords='axes fraction', |
| 35 | + xytext=(+0.5, -0.5), textcoords='offset fontsize', |
| 36 | + fontsize='medium', verticalalignment='top', fontfamily='serif', |
| 37 | + bbox=dict(facecolor='0.7', edgecolor='none', pad=3.0)) |
31 | 38 |
|
32 | 39 | # %% |
33 | | -# We may prefer the labels outside the axes, but still aligned |
34 | | -# with each other, in which case we use a slightly different transform: |
35 | | - |
36 | 40 | fig, axs = plt.subplot_mosaic([['a)', 'c)'], ['b)', 'c)'], ['d)', 'd)']], |
37 | 41 | layout='constrained') |
38 | | - |
39 | 42 | for label, ax in axs.items(): |
40 | | - # label physical distance to the left and up: |
41 | | - trans = mtransforms.ScaledTranslation(-20/72, 7/72, fig.dpi_scale_trans) |
42 | | - ax.text(0.0, 1.0, label, transform=ax.transAxes + trans, |
43 | | - fontsize='medium', va='bottom', fontfamily='serif') |
44 | | - |
45 | | -plt.show() |
| 43 | + # Use ScaledTranslation to put the label |
| 44 | + # - at the top left corner (axes fraction (0, 1)), |
| 45 | + # - offset 20 pixels left and 7 pixels up (offset points (-20, +7)), |
| 46 | + # i.e. just outside the axes. |
| 47 | + ax.text( |
| 48 | + 0.0, 1.0, label, transform=( |
| 49 | + ax.transAxes + ScaledTranslation(-20/72, +7/72, fig.dpi_scale_trans)), |
| 50 | + fontsize='medium', va='bottom', fontfamily='serif') |
46 | 51 |
|
47 | 52 | # %% |
48 | 53 | # If we want it aligned with the title, either incorporate in the title or |
49 | 54 | # use the *loc* keyword argument: |
50 | 55 |
|
51 | 56 | fig, axs = plt.subplot_mosaic([['a)', 'c)'], ['b)', 'c)'], ['d)', 'd)']], |
52 | 57 | layout='constrained') |
53 | | - |
54 | 58 | for label, ax in axs.items(): |
55 | 59 | ax.set_title('Normal Title', fontstyle='italic') |
56 | 60 | ax.set_title(label, fontfamily='serif', loc='left', fontsize='medium') |
|
67 | 71 | # - `matplotlib.figure.Figure.subplot_mosaic` / |
68 | 72 | # `matplotlib.pyplot.subplot_mosaic` |
69 | 73 | # - `matplotlib.axes.Axes.set_title` |
70 | | -# - `matplotlib.axes.Axes.text` |
71 | | -# - `matplotlib.transforms.ScaledTranslation` |
| 74 | +# - `matplotlib.axes.Axes.annotate` |
0 commit comments