|
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