From ecf1553b4a520cbea42bd44d429648130e5d9597 Mon Sep 17 00:00:00 2001 From: trananso Date: Tue, 19 Mar 2024 16:11:22 -0400 Subject: [PATCH 1/5] Implement align_titles based on align_xlabels --- lib/matplotlib/axes/_base.py | 9 +++-- lib/matplotlib/figure.py | 66 ++++++++++++++++++++++++++++++++---- lib/matplotlib/figure.pyi | 1 + 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 23cc1c869c07..0164f4e11169 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2985,8 +2985,13 @@ def _update_title_position(self, renderer): titles = (self.title, self._left_title, self._right_title) - # Need to check all our twins too, and all the children as well. - axs = self._twinned_axes.get_siblings(self) + self.child_axes + # Need to check all our twins too, aligned axes, and all the children + # as well. + axs = set() + axs.update(self.child_axes) + axs.update(self._twinned_axes.get_siblings(self)) + axs.update(self.figure._align_label_groups['title'].get_siblings(self)) + for ax in self.child_axes: # Child positions must be updated first. locator = ax.get_axes_locator() ax.apply_aspect(locator(self, renderer) if locator else None) diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 087c193d48c3..fe16997e2131 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -132,10 +132,15 @@ def __init__(self, **kwargs): self._supxlabel = None self._supylabel = None - # groupers to keep track of x and y labels we want to align. - # see self.align_xlabels and self.align_ylabels and - # axis._get_tick_boxes_siblings - self._align_label_groups = {"x": cbook.Grouper(), "y": cbook.Grouper()} + # groupers to keep track of x, y labels and title we want to + # align. + # see self.align_xlabels, self.align_ylabels, + # self.align_titles, and axis._get_tick_boxes_siblings + self._align_label_groups = { + "x": cbook.Grouper(), + "y": cbook.Grouper(), + "title": cbook.Grouper() + } self._localaxes = [] # track all Axes self.artists = [] @@ -1293,7 +1298,7 @@ def subplots_adjust(self, left=None, bottom=None, right=None, top=None, def align_xlabels(self, axs=None): """ - Align the xlabels of subplots in the same subplot column if label + Align the xlabels of subplots in the same subplot row if label alignment is being done automatically (i.e. the label position is not manually set). @@ -1314,6 +1319,7 @@ def align_xlabels(self, axs=None): See Also -------- matplotlib.figure.Figure.align_ylabels + matplotlib.figure.Figure.align_titles matplotlib.figure.Figure.align_labels Notes @@ -1375,6 +1381,7 @@ def align_ylabels(self, axs=None): See Also -------- matplotlib.figure.Figure.align_xlabels + matplotlib.figure.Figure.align_titles matplotlib.figure.Figure.align_labels Notes @@ -1412,6 +1419,53 @@ def align_ylabels(self, axs=None): # grouper for groups of ylabels to align self._align_label_groups['y'].join(ax, axc) + def align_titles(self, axs=None): + """ + Align the titles of subplots in the same subplot row if title + alignment is being done automatically (i.e. the title position is + not manually set). + + Alignment persists for draw events after this is called. + + Parameters + ---------- + axs : list of `~matplotlib.axes.Axes` + Optional list of (or ndarray) `~matplotlib.axes.Axes` + to align the titles. + Default is to align all Axes on the figure. + + See Also + -------- + matplotlib.figure.Figure.align_xlabels + matplotlib.figure.Figure.align_ylabels + matplotlib.figure.Figure.align_labels + + Notes + ----- + This assumes that ``axs`` are from the same `.GridSpec`, so that + their `.SubplotSpec` positions correspond to figure positions. + + Examples + -------- + Example with titles:: + + fig, axs = plt.subplots(1, 2) + axs[0].set_aspect('equal') + axs[0].set_title('Title 0') + axs[1].set_title('Title 1') + fig.align_titles() + """ + if axs is None: + axs = self.axes + axs = [ax for ax in np.ravel(axs) if ax.get_subplotspec() is not None] + for ax in axs: + _log.debug(' Working on: %s', ax.get_title()) + rowspan = ax.get_subplotspec().rowspan + for axc in axs: + rowspanc = axc.get_subplotspec().rowspan + if (rowspan.start == rowspanc.start): + self._align_label_groups['title'].join(ax, axc) + def align_labels(self, axs=None): """ Align the xlabels and ylabels of subplots with the same subplots @@ -1430,8 +1484,8 @@ def align_labels(self, axs=None): See Also -------- matplotlib.figure.Figure.align_xlabels - matplotlib.figure.Figure.align_ylabels + matplotlib.figure.Figure.align_titles """ self.align_xlabels(axs=axs) self.align_ylabels(axs=axs) diff --git a/lib/matplotlib/figure.pyi b/lib/matplotlib/figure.pyi index 687ae9e500d0..eae21c2614f0 100644 --- a/lib/matplotlib/figure.pyi +++ b/lib/matplotlib/figure.pyi @@ -161,6 +161,7 @@ class FigureBase(Artist): ) -> None: ... def align_xlabels(self, axs: Iterable[Axes] | None = ...) -> None: ... def align_ylabels(self, axs: Iterable[Axes] | None = ...) -> None: ... + def align_titles(self, axs: Iterable[Axes] | None = ...) -> None: ... def align_labels(self, axs: Iterable[Axes] | None = ...) -> None: ... def add_gridspec(self, nrows: int = ..., ncols: int = ..., **kwargs) -> GridSpec: ... @overload From 2ff72be64c65750b4f42706136e66f590f33e097 Mon Sep 17 00:00:00 2001 From: trananso Date: Wed, 20 Mar 2024 11:25:22 -0400 Subject: [PATCH 2/5] Add documentation for align_titles - Add align_titles to api doc --- doc/api/figure_api.rst | 2 + .../next_whats_new/figure_align_titles.rst | 7 ++++ .../align_labels_demo.py | 38 +++++++++++-------- lib/matplotlib/figure.py | 3 +- 4 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 doc/users/next_whats_new/figure_align_titles.rst diff --git a/doc/api/figure_api.rst b/doc/api/figure_api.rst index 937020afd8fc..2371e5a9a863 100644 --- a/doc/api/figure_api.rst +++ b/doc/api/figure_api.rst @@ -71,6 +71,7 @@ Annotating Figure.align_labels Figure.align_xlabels Figure.align_ylabels + Figure.align_titles Figure.autofmt_xdate @@ -264,6 +265,7 @@ Annotating SubFigure.align_labels SubFigure.align_xlabels SubFigure.align_ylabels + SubFigure.align_titles Adding and getting Artists -------------------------- diff --git a/doc/users/next_whats_new/figure_align_titles.rst b/doc/users/next_whats_new/figure_align_titles.rst new file mode 100644 index 000000000000..230e5f0a8990 --- /dev/null +++ b/doc/users/next_whats_new/figure_align_titles.rst @@ -0,0 +1,7 @@ +subplot titles can now be automatically aligned +----------------------------------------------- + +Subplot axes titles can be misaligned vertically if tick labels or +xlabels are placed at the top of one subplot. The new method on the +`.Figure` class: `.Figure.align_titles` will now align the titles +vertically. diff --git a/galleries/examples/subplots_axes_and_figures/align_labels_demo.py b/galleries/examples/subplots_axes_and_figures/align_labels_demo.py index 88f443ca0076..ee7cac7be742 100644 --- a/galleries/examples/subplots_axes_and_figures/align_labels_demo.py +++ b/galleries/examples/subplots_axes_and_figures/align_labels_demo.py @@ -1,37 +1,43 @@ """ -=============== -Aligning Labels -=============== +========================== +Aligning Labels and Titles +========================== -Aligning xlabel and ylabel using `.Figure.align_xlabels` and -`.Figure.align_ylabels` +Aligning xlabel, ylabel, and title using `.Figure.align_xlabels`, +`.Figure.align_ylabels`, and `.Figure.align_titles`. -`.Figure.align_labels` wraps these two functions. +`.Figure.align_labels` wraps the x and y label functions. Note that the xlabel "XLabel1 1" would normally be much closer to the -x-axis, and "YLabel1 0" would be much closer to the y-axis of their -respective axes. +x-axis, "YLabel0 0" would be much closer to the y-axis, and title +"Title0 0" would be much closer to the top of their respective axes. """ import matplotlib.pyplot as plt import numpy as np -import matplotlib.gridspec as gridspec +fig, axs = plt.subplots(2, 2, layout='tight') -fig = plt.figure(tight_layout=True) -gs = gridspec.GridSpec(2, 2) - -ax = fig.add_subplot(gs[0, :]) +ax = axs[0][0] ax.plot(np.arange(0, 1e6, 1000)) -ax.set_ylabel('YLabel0') -ax.set_xlabel('XLabel0') +ax.set_title('Title0 0') +ax.set_ylabel('YLabel0 0') + +ax = axs[0][1] +ax.plot(np.arange(1., 0., -0.1) * 2000., np.arange(1., 0., -0.1)) +ax.set_title('Title0 1') +ax.xaxis.tick_top() +ax.tick_params(axis='x', rotation=55) + for i in range(2): - ax = fig.add_subplot(gs[1, i]) + ax = axs[1][i] ax.plot(np.arange(1., 0., -0.1) * 2000., np.arange(1., 0., -0.1)) ax.set_ylabel('YLabel1 %d' % i) ax.set_xlabel('XLabel1 %d' % i) if i == 0: ax.tick_params(axis='x', rotation=55) + fig.align_labels() # same as fig.align_xlabels(); fig.align_ylabels() +fig.align_titles() plt.show() diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index fe16997e2131..0a0ff01a2571 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -132,8 +132,7 @@ def __init__(self, **kwargs): self._supxlabel = None self._supylabel = None - # groupers to keep track of x, y labels and title we want to - # align. + # groupers to keep track of x, y labels and title we want to align. # see self.align_xlabels, self.align_ylabels, # self.align_titles, and axis._get_tick_boxes_siblings self._align_label_groups = { From 1dee172aefe6abd53a257fe3fc130baa5cfab37f Mon Sep 17 00:00:00 2001 From: trananso Date: Wed, 20 Mar 2024 14:00:17 -0400 Subject: [PATCH 3/5] Add unit test for align_titles --- .../figure_align_titles_constrained.png | Bin 0 -> 35117 bytes .../test_figure/figure_align_titles_tight.png | Bin 0 -> 33777 bytes lib/matplotlib/tests/test_figure.py | 26 ++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 lib/matplotlib/tests/baseline_images/test_figure/figure_align_titles_constrained.png create mode 100644 lib/matplotlib/tests/baseline_images/test_figure/figure_align_titles_tight.png diff --git a/lib/matplotlib/tests/baseline_images/test_figure/figure_align_titles_constrained.png b/lib/matplotlib/tests/baseline_images/test_figure/figure_align_titles_constrained.png new file mode 100644 index 0000000000000000000000000000000000000000..78dffc18e20c987fd149ae3c6f8d17c25117e547 GIT binary patch literal 35117 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 literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/baseline_images/test_figure/figure_align_titles_tight.png b/lib/matplotlib/tests/baseline_images/test_figure/figure_align_titles_tight.png new file mode 100644 index 0000000000000000000000000000000000000000..f719ae6931f0b0bf9b17cf6964e0fed8ef818c8c GIT binary patch literal 33777 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

iIA^e6@czY%A*iWM-i>t(CBBAReBcNB1y77 zT395oU(R}h4`(+Zh*K*x#(+?}cQ}uaIMb;e9c(o2M7QweoE!tDOBa+-FA)m&B$}~= z5p2gM^*n6aoG4Mc1rDUp4@)=ZB*gO1%Wop-PJH+%#T542nVe&K&&(2!C=F!uqJm4)%m6f-)hGIr?605V0!3D2FuJkQNy+435!)RtU z3L+NU$eqJ(>v=>}Gk0%%RFoiubn!o23PIiH24IjZ6QGc(W1;RT!SO=t=^Hq$nFZa9 zYp{rriJsNIed45H6qh0?IyKEqK$D4$`pWtfElgw&j*Sf3%j}QoV3+?g+B6aj@P9$nz(z-F_Z(DU}S7eVYJZxq`UO8W$Nfg$KD56gx8kdrsM)K)W%{0 z(|kpJJqI3GYM~shdv&rN5Wi5nVhok1_a=zDkiQdDHrbdU6NkUvzYoU&{`$8fmeDeg xUNs7T)J~NRF6LQJJz`o+m4{LE|L6bEU2OUy^2g0Sl#)=?#`T*uv(zn*{}1D0 literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index 8ee6aae99361..ee9c54d18159 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -66,6 +66,32 @@ def test_align_labels(): fig.align_labels() +@image_comparison(['figure_align_titles_tight.png', + 'figure_align_titles_constrained.png'], + tol=0 if platform.machine() == 'x86_64' else 0.01, + style='mpl20') +def test_align_titles(): + for layout in ['tight', 'constrained']: + fig, axs = plt.subplots(1, 2, layout=layout, width_ratios=[2, 1]) + + ax = axs[0] + ax.plot(np.arange(0, 1e6, 1000)) + ax.set_title('Title0 left', loc='left') + ax.set_title('Title0 center', loc='center') + ax.set_title('Title0 right', loc='right') + + ax = axs[1] + ax.plot(np.arange(0, 1e4, 100)) + ax.set_title('Title1') + ax.set_xlabel('Xlabel0') + ax.xaxis.set_label_position("top") + ax.xaxis.tick_top() + for tick in ax.get_xticklabels(): + tick.set_rotation(90) + + fig.align_titles() + + def test_align_labels_stray_axes(): fig, axs = plt.subplots(2, 2) for nn, ax in enumerate(axs.flat): From c947700796ed0351bde362c16771d78d82196ff0 Mon Sep 17 00:00:00 2001 From: trananso Date: Wed, 3 Apr 2024 14:00:50 -0400 Subject: [PATCH 4/5] Switch gallery layout from tight to constrained --- .../examples/subplots_axes_and_figures/align_labels_demo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galleries/examples/subplots_axes_and_figures/align_labels_demo.py b/galleries/examples/subplots_axes_and_figures/align_labels_demo.py index ee7cac7be742..4935878ee027 100644 --- a/galleries/examples/subplots_axes_and_figures/align_labels_demo.py +++ b/galleries/examples/subplots_axes_and_figures/align_labels_demo.py @@ -15,7 +15,7 @@ import matplotlib.pyplot as plt import numpy as np -fig, axs = plt.subplots(2, 2, layout='tight') +fig, axs = plt.subplots(2, 2, layout='constrained') ax = axs[0][0] ax.plot(np.arange(0, 1e6, 1000)) From 0be9cca9683f7ca632f0ed35bf380d73b3d412c0 Mon Sep 17 00:00:00 2001 From: trananso Date: Thu, 4 Apr 2024 11:11:50 -0400 Subject: [PATCH 5/5] Increase error tolerance on image test to 0.022 --- lib/matplotlib/tests/test_figure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index ee9c54d18159..58aecd3dea8b 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -68,7 +68,7 @@ def test_align_labels(): @image_comparison(['figure_align_titles_tight.png', 'figure_align_titles_constrained.png'], - tol=0 if platform.machine() == 'x86_64' else 0.01, + tol=0 if platform.machine() == 'x86_64' else 0.022, style='mpl20') def test_align_titles(): for layout in ['tight', 'constrained']: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy