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 zcmZ_02RK*%`#*k=$jFv06h&s)LK2ZOl4Ori_9k1%OIDJQy+T$hd+%hW%(Akw_nyD| z==1&je*gbvr)#sDroacEy@A0@F_v1c6D);1x3FrtA1R++qEvtqg*ggn?HHLp0 z{zb5RXcGQ<=y*%h@xG0zql=-v33Aua(bm$&(ekO$d1n)Qho?5yS9wHv_;?ifFEUAnS2L2Ge(3wMI;ZM&eO@y3`jEt7XI2&h3F;ByI z@mCSCd4)+EwTP(bpNi$`3gh2qNuJak%88Au6D`Y}(Hc2TTZ_N#Ccl!=(9;_?V#s#- zYmR!8TbyTq;D$>biAe5@`N>Jyn3!BV+8;eO>Po!+wWFhHVes?n)^8hOx9fZP+(#7@ zWJOeadyIK1mu&Yoo?f_k@kX8o8!IceK#(a;QBm>fOc0-FAdy11FpYV6 zV#2RAlB1**N8Vg?Z-?=)>72g7(ZQ}twtD&gd!<-xW8*3=tBuzqRf>ImeS$~)SOz;Q ze@botU<+KmYB9tc*=nx7M;Cg!si{eYGwSZUr%f-Z2Fe^bH1f0pp8kA~g-~;A`MZof z!%LG3HSc3exfyuYaAmAc^P_?9QuV0!F(drqlRJNxS4OLz;EnL3B z%^l$9=Z8KO9$?%O76jf;NI^kiXlZ3kjlh0o*dx#A>+5$H8p~rzhtOV?%jz}P zt%$v9Mj$LK%*z>%=FAxxd=>!#0akz{JEc49 zHr)}&@mL_%*3OP>xWeTe`qpqRtkgxD5Ha285G+Fy={ZFoqM?KUd6NptRX}Ep+ zHtZGbn5IR7!*n|tvb1yYnFW^X!H%8bzNimb=sB z3Ekb@?KWmqhdsre7f4|V9$SNE<@=_c@t5H^X@o3ezIJt;lfjR8_l}c+k+CT)T=Ij( z!$*%UBbcV(bN%1G7&Q@KNqZda{*}q;1>Y!jT}@rt*q~&S1HZ3$gp`+-&e&g$`sP;h zK>y1Y&grXHukxFGqx`eH%!}GJtbgFk)5x!FZ4^l3Lw(N-3vE?ZmimSUTm-!YwLQ25 z6B3fUIcxw4?ftz3PPfguiwq15vVmtAPa$MXO!-`t(N`X^!atot{wyu!yX(Gw{dy@T zjwt%gXm^Pb)`072apHFHnTWS zdi9q@!R$TiGW#h4pE(L1>nTW>2L~Q+-n<#&A1!y9=Xe@>%r7t!R?L@m%TNM%pW8yLIMcBeE)rNax(Jt>C+u>R=crUtc8I>9Au@Q zkarA>1RH5=YMRxH2Fn}ezp8rQe8%P4uy_>%&H%ZQk@@Wz?$N}8IQRr6OVgC4j&{Qmv>X=XlH!^qYy znpjaEE3cX7szkToPeY*bP^sMs!gwCV^>7?QL(#9m7ca&k>-HTUE`079hZrPpX?Z2l zW3BbKDXX~x@nP6|ce9VU1_}yiAUE1hevQy-D|cBAOT6xm?X#2~Qr=0_-qjVT!xQM| zcQY;NcVpuzJQAkdqJ=s<=1E%Dj;xHMVVisV6AKF-zpo&#-n{Yu^5qL%TW)Tyc>=!C z)2ELt812g#WH92?KEg>{U^*k)!+A|@9f@)``+nfPOi4*`vAnOR7xv}LHKiE7l)g_N zKYkP=tgZIk@7vMliB5w&QRLHVlr6HfUz2*K`Qc_ToP*A{o<;oR! zu)4(~H8t{s!$U)J^ItQ6i$8zVGT{sOtHelr3&!tZ=&6b%g z-&?%5`z z=l$kL^1x1hc9wG9*v5v$!C_sisu`K948LvOvC4RNJO3_~kEEpJ$IqV|)~4D}A4h@C z*RNl*J}>%_NMgWUnE~C3N$$6AO3=`YZ4DKu_bfj2e!`TlNs@$qh#w+d{3W|9}3 zf`Wp`v$YF=Rq*cIX{#vzRe!L%4*4q_B86c~7~|J(-|E4vRsed9&t@hy_vSpb+28Sj zqNx^=X(7NH!1QltcmF0$B)E*!p?(_`6#yp+iIYHjv#SAJ z8syIxkd0XR`N^I=dxi-QZ-KRF8DG)7**ayvu`oyh9#H2p>KS<5eQOM!gZMz8XXD_& z0|z^QmPrCLG^BHZgTojws_VgO3;m%^UX&yg-?bMJ5o8d!3jwpybv@A3bXBJKvsU~1 z-5m!{d9%ll4R+V2G^;(zti6V)xHQoJ7k};}i`G{9M8(hV_d5cz66;TJ(!hWwLOSZP z9!i?JG|Twy+qXujK~Ug;Bv)+CbfZBjS?)LFzI%X7XMef6xxGBx-xj{)t-Fq}b8rN+ z+n%6%~YKIy?v@l#tUVPw#5&*SMRQWVk}k z13VqHvUU0$cH=8JmcA!i9ZfKq58v;R*DxGM zonXCuSpiatP^(zBAq4EI^mN&H5j&Z9Nzd{TZ{s2@?#{&PT!5Nn-Q3Ep6RW4~p}HWW zr|06)tJF->eA1CVLVL!}29GH8G7^x*GYyE7OX=?2fRd7uoykb$M(?9_WVKBbY!9Hu52E&I}(J^Vu@8c4d~9*-JOk#i}3R0%QPak z=eHIH@BgLbmz6zkWRhl0)wm=n$>e>s%K@0zz})<0a`Jhok;aQDo>PzwqgTKmoQ9jX z{{4;p3MhlGwI2}_01EJ3fu~@y?m@u{0Z&#>PcP2|90ahf#E+jp!SvwB)vvi$@m6h+ zhcSrSD-U|@&2pd!w`fVqd4VQ1EzRy=XVqQHTf61t&U23+KlTUUfDh)yca1J|=_u!6 z0lX|J*x;=jH?W`%#m`V19NRpCaC!Ug-KtDWv(ETBz%lRlwbQ!Cf;bXuzecbX0tP2y zmSnj9UJ0wqDUY5IeTxtMfap==1(%dRZf!Bofio4_4Re4PHN=xB_$(M#X*04WqVs5*ns!S zNqROF@RFx+ac7U104v^05DVyt6P|$Tp?jE_h6Z!-&RYbL3!(9yoP6v7!CAAynfvHq zT^X(E9~S5V+{Qx;;PnBaHv)+P#qBG)uFL+?aK-?i&4-o&=>q0hhFAdLIa`@K*Y&t=>@Hf;`U)$SdrKP1qoneQ)Lu&#_n8RRQI0!&J z12eNg2>8p;6lv0oY z4hwAFMWL_7{t7M#H=g_im)9^gJ;$G*q3i0UBypT>#PSpfUUv4=fVqg>DpL&qJg?6{p%Jb|fgUli4a0}`Gw(Ge-|!=)rF~>EG~6+3q@%0*2MnSikYr-Dg}I<; z37%xUG1Cnt{7p?w8g``^pUgxz0>r?=A{ZsXz&?Pdz!@4IHZ(N!MPCW{Hz!j@L32uK z9vw^|lN&y~o$GiI$4VB>*1GZtO0gpvsjfg z3b?CgpnJL@SZcKm;@m#DFOYA^pFXV>TY<^+mu&YwWH{yP4D+t33iWCsv}l9F=fz3-W`XXPrK7p?b2{_WD~7wagwts30g z-rflHl*L^=25RaTfU(J)ot@R>Ed`gRiXNZ%MG*#~#8|*NJs)@mKo@f*JqBiG5;itA z%h77aKY#wH$@jW%?`eHPb6~2e%kG+qV)VK-kyr5uF^Zd-jL>iY-)}N)VqQ_WZ0giaQ)jOSl3wzWmzS>YI^aLdaps2>31-0Qeukg~*3YPTFfvNXaQEfO8_z zsqtcjU=8sLkLlSYS<&Lw@=lctcXTGNlR6cXKdV!rawRjFHB1pl~RZYxD2(uIuP#{fE zLVbsLPOa4M24NLmX7)(0*pe3N|5q_F7@!WMb9#+nTU?UU22?jT zKCWgKN5OF~8GLwAga+`KM0;8;ifsfw6}zb*w=a`2z*gZ3TsHDsSXF z1f^*bWm#FPZxG49XDTzJ1sw&uQkDbJ*jsLGK9?n(PW^s-pfzn>Tng+)I}Ue%Dc3|s znmhX0;Yb<9opV2TK&}OIR$CU^_=HqO3Xizrz(%793vDc*j2V<3DDwq5HV6mrY%*jH zs9IR{o=s6fX+H#|Icm9GeBh{Zzab61z4GWe-~r>oPbTGOT)DZq$ruOr{|tF% zk2e(+6)=r7$QVGyC$Q_GQ)peKlEat&PU8CYKXY?0;T(J2e}qIuQCYjZlh5HoK7abO z0yVMG@<gj6GF1y> zBctaJ^`7BEkwxH7dI{J_9iG2I0ik1m{`kTU%pEZaJieWm)B{COC=}gLZWcLKYWxK< z$}cn1tg5Z5vJ#NWl3R31Ird6V_I;I{-hm1iUN}!YmQ((uuiB<=D=PjdYU}E10T#?@ zIH|h28by$h3%@2k55mmkw>}mCYDtkXt@mkvJ|py)!04`;w$}m`uXRavUdZcU=QmHu zmoJS#Eod&UX*@)xr>5$F5rXI=xa2(@YvwqdytK5$clBz{>hEnha=_R2_5vsQP2fph zKC;l0O#yiU1+Y82yO2Y#U879$+@gIM91O)M9#VeU1fr4l6)p%!5t6U(FedXroVtDQ z9-4Wv)RjkH$H#|MR!R^th>+g6aRU&Uw1x&X0v{l|%Mt@J1}%+SP@NST)L}#a z07?%7=(wO~@z)H^!hV_2xMLA)^565cg@@DQx~^|C0O9xoN)4c!iNsx&{Ijz!qsKfw zeVUMvP$^ab7g7|0!2dpgL^S~2A4@AM6a{Q-I9mQLCT?!d%l{dP!EC&eNvQ>tjT<1t z;`Bx%w7~f1lZE-L{^;iwk+9^)W@Zh&y+xh(o1xZ3^DE@GuzfbxRQ3mIYS`l9;?RXz zPk-fJ+h6$f+Ln`L@30{c56@=jx3lV9oFhQ$Q=@rXHvM>G?H`;lmvrmJfj5kZio%6^ z=@t56ZW{@6NNfQh(XnaIe)P^|X$cK_(;=pKFu z5X=A{t=*e^i(l?vFu!Ac$T0taBsnyc*k|q)1HPi{g*?EJuFsy$R>u(&Z!7dr_iT&y z>sMyC>j1!q*VZ5VDUA zHs-DXA~L6khoenaKpK$H`!(OIa~1*(OG!xo^urmXnZRfP$vz z7i{DN95(P1wJU!b46Uqmb2`8}$j+U^J9q9J@be9gjp?n$5m|yKa9S`HB1(Nn2QeB7 zZ{NlT%1G1rnYA?!HVzKIMcEef?+-|yd5VEICA&J;yLD2T~w zg|d4hn73M5Mn)!~?Qd5S3A7x5ubP0hV_v?jhq5aoF)`nQ0)82I!3oGtD5!?Kf%YXJ zK_Jkb6@7m@pcyvmA(0`{Fwr+&qj);#Z%1{e}XdyJe zMNvfUas|06AYeP*c!rXSO7KYlitYfqZ!M3KgvvP->;lTADgz3M&w8j-%)9SFw)#M| zr#Pfd9I$qz7N8+&=Xu&C*jY!dTa&GkX!FT>{MWPfX%>iRcxM?91jT2UI63R@@K&8d zAjqIqi`~q3mdB>1*a)-+#KC+F0qY|O@KEjV1PP(Qea@td6?I!+liJ5+uDPI%-lo!b zY|J26uZnJ>C0yRsRRkJq?*w?s$cof}NVvqyD{o+syd(*12?RdC!Pv;XBuQcffbI7p zJ0~ZoBjrPd{_&tci^|G6y^DAMt`Aw>2O2%CWHkvQj-sNX`4HyU2RFi6ai@tyodSqnnH3P>hdWHkiwNMwO6K9k;MhnhDg9SgY!RQdG&b}UXJ%&J zE1*w!r=wTZR<_BZ$>MJvtHV>U&hbmUh)m{MR)>_skU4M#mw0&khQUMVDuQJ5(3QJ^YsA|>oZ~5eR|6Tzuc(3+N@t60B`%rj`VJ2d<7eT- zdjBjan{Y`4={Adyu;=d|S3K&G`Y;_})f9cIRx3|4ag5Z;o1lH6@QD4zS zq7(z_>t!mpN8F*+Lx_3Ghlmu(A{q$Epi@giW;!{uqXXQcDvlY zc>d?(QG!jUlC~*(*qZ)bnv?Zw)o|#xv}seYoZ@52#W`BH6&`lv1xj3x^?SDPA?j}pd*i}7oY(9Fs}r}YcphZ zyM+N%4UqyH`Vn$6U=^o%Kv6A#t5$$=Z|LqOgC8}0G;Bc0rJ@0g8$ClBOx4&?a_8Io z$!?5Jso=xF9PW{_`$`mYLxS;r5P>d5;jV5y%qnII+nhZiw4oCh4+z87Rla zSFY?{xxbvqt#yD^dz0k4&O+Il0)#QN37=T!gTRH9b9z)_I#cD0YSf4xsmxnVA{T;ldqqod?Jo*37bO08a<9}o zjalD@WNfi~70aMI^%fd{@(=ihz>|y&4!FCx~&@`n^y)@Hcmd}<6^9>+B@BjY0Up?iCBpcvBDDN_wQqgr_Bg9^*{HYU}`n+DcK7o4uJ zn#(=lB-S{5MvL&dXC3R3Y>pYS0>AL)k*4n%E@Rs?C12}B%R+1OOSv8I4q_598|{4* zw56)=W!>EgCFo}C`sdLE-t%qpt-7I%`jt;FbG~;s5zw>B7@9q0MelFQ8A?6M^kL~R zPB5KKX~{5`7ocCNMtZVN5Ul5RTY*n>8m`c-Ex*r#nLk+tPKi@|vdzmP@9Z;m71$Z! zNvwl1H7n{;zPjO$51KmPxcw^fMA6GDbcfe-$yI-+_7YqXkHJPTrCr;JE&FKgZH~+N z##~98J}^C(T;x$KtC#?hUf5f;7S>eiwf(aB+Z|kid1d_UTl2PE^Tx3H^uHg}>6G-n zu{nMc7+P3|5R)0MxD>q=qb4gNWjXbh={7E+L_3Bq%k zp^3S_(@&Z1;RcO4P1&C3VLIi$SNmTY8XEau#+k2KyK9Ux;y>=w<<$m{UNq3R=V=d_ z(iFUS%2Q0_He)bGYv2b?ukmqnfU{59gTrWLOCr>6+-~PkxmvY6J+K#}XO|Q35WkFn zC?=+Ga(z$^E~ZKip>-l^9)kHKFP!b7;0+WE z2J7Yuy_GjMWyQsV*|pK#XT8qqUmNJoV=%1$^i`{ma^ga0pj&YydiD9sIW+r`4lL1F zR|9thXUkD`Vm2ZJPwnG@$|l*dd-!JKgr~&Cd$O`>yVJ`fH4#!`<;%_CDlf9w%T7WuqryU_zlG*X11(b9UdOmvZ|faIK^F1mQ!rQI zggQH7aL;w!gBiW&>+j17{i|zzviMj^3;kFH$2nY}59uky+?L@Y(f3tk`(BX7_PjFA zY)Kj2V{%as{{IFs8~4ifC*bX}r+I3Wd^=ixVj-Ucg+>doP{4M<_COKK)KUa1LoV2R z)3HTfdEy4;0O0()3d973WOnN&=cL?>TTU{9|JvG z!HSn`^ zGcV=xu(oGY9|eV*8@)!jw<^({f2SFx==ar$!X^FDvlOrT6qA=*7m$++eMzyI7ZjTJYJQxL#7dH+^$BznS{9TD%5u8% zjkDR8@Y$<2pIE=c3$3*ftY(-zs-$iS`yC%M%?GsXeTfz!Bb%)-!Ml%zu(`X}whSu1 zCOWyRT2DmV&PI4J;&U9f@M6`F@d9}H-jcl@EnrGwB<8yMe}YZ7?jU7c*tVA_3F5lz z+lgW5S@SCm%G!M7b%{y_X(%sO6uU)<26?$X{v*1PomC>lVER>ZXdM%Y!L8RC*Jzew#Qaw~4^Fre(L9T>7EoZ27O;{NIn)9n` zgy?-wi#dYl+DPJtYK#R{C%W!;GhI2tWZeK;9Pp4}^x3HLMoz8^s)`SfrN1YgK}Iu} z!zk&IdT!Dle7uLxB24cVq~wuA=hCjxM{^=48*qUo4WDfOUb13F)5rY$or7#?8v51w zNDSTkbj1KCZ(UrZooTM%Tn)nteF$bosM9RkU~O*V(*3ONnly^HcV`Ii8+$pCt2W$f zNl*Er7F0iovz}Yn+P{O>t;dTR8Ohn7b`0@WZ zZr*q0GySg~=-`@JT$P}myzCTDhpzuH4;HSF6UHW3z_7T`UdS&%WL-Rcvi{p?R6A%c znDz76v_9ZN6AUs%AoxC4G|XY}qHVEIL-SWYS5YlRG<{`{zRsVp*Aunu2<1;nD(SH^ zNAbhy0>z9QljRf`W!~or0cTR#ZgzJ!X`u$7c!uTUf&nyezDetA&i^^{7pGmsJs4 z7LsXp``kqG=LoO+$uE?gxUT<4)ODjo?heDtM%?&ejyt_95~|;&6PO*rFnW(bE~_97 zTrn#uxI)Wk;vs>7`33pO~rwG0wOZ_m1XN!s->KWW(4Z7%?o`z+I_?=rj54jg_UxD#& z@y7BOO6VhOOjT3nig6`-a_}G4kKnyo3vbok7$Z~5Klb2c;1e+0qUNMD1Z9>$+eju8HD2# z6Mz2x4FpL|U0)wHRGBnlj+fB3#NuKoG=Yp-Utf$7w0LXH2;vnQexp-5Iywf>dV}7& z2k0SO$9(Y|Q6?n_X!sQ9|3ZZ;2f8z$Bf_BqxLr8d)2!Rc)lgve84LWQcX>o=?5q?P zA&c$KiXpVX*;rUoZg7PFXAOlkszgjnO-;QlKu$LN`EKE?>vHru;`30>QLfRmnw&#G zhwvPae`F*DkA8IsESLqv;h?as1AW99Bu2_x5n2@2IG!*g6O$HV_tjtCFt%!X-<05QU(SH=yG&Zp*?GQ z=ALYiid3W7cqnrhk|imSM6tvRr|=d8m2ku{?=+OdQT7@70H`t&j`@G1YY?cEF_9d~ zMkAHa%9BF>0_U8Ydj%CxA}hd~r$DO`RbwF1Jkb*%4s3?zJ5=q1KjM_EhKf=ZJ-p}W z5CdnfU9apC&7oN= zP~H+1X&Cq zgoK9j8`L5?70!9IMxb~ZtRpOQ^>UE7rsd0jBT;kXHVL)28`=%5y{~*d02-+cLqiN; zIxWy?;{##WGp5 z0B&*P0}|z!>tCEUj<7Z zC&Uk0j7FW#mUd!}lppvZ3&UrbCA;bEMT4b0Px=th6oCl<9FPLMP?p?1h4!6*^k<2F zxct_iRFH|y|2ubN+f>n8;dBtT$;D}NYkovvXrx?QPOka74OfvTWX&6pH4$ZTq79eV zu$8^fsBNDMRqD#MKmM5R7v5){$#;YRpenzKC#3N4 z@$%i)*4FO3xD!CdLkt9Q7M;}U^od;JZa;|YGMgR#PEXIh?QLprCxX`H-7guB@fAO) zYkFTHmfjqw>DwT@nGkq`SQNXW7uZphpS=}K{Rilw9neUl^B9$fTfa9YMJs*>Wo0L{ zan?=twy5U!pa%5z9-8AjpB3=JC=n2d3yX^uL!hDxhu+Q3&Q9&%AT2N^YtAA9b9=xr$}Y)XkXNfGdw5x z@%uw3FD@-@ZBV0p>g)a~6`pTh1Y&SBJfKRV?h+gQ5Jqw8<*IF_5$|KqOHtp%m>ZUy zS3jF`{+fyX(2r6i);NBKE4{gZoo9tnNWe`7AGWo% z4Nc=p-kX`7?(WS4UUyC+^?tTGs>G0NhGT=-3qfmHSr<06cu6yg(9f6c+A2ozwuWi^ zydHC&RuRG5w{Jlqga&g|^9+6EF_4pDA*lWe|I8U*;PIe`UT8n12<@1>=8x%FS(ly^ zX~AevU2E$ZR2c@Xey18WT9{6Q044&GGhq3?=j)1VYH1nG{>XT3d9~=ew({fiH9BXM z@qp?WV{wX?iwr84`+*IU8qE-a>>vgC`}-S!Xg22BQ*u=41R?2)))#ye6O)~dpUTjj zTG;JTLdEU`nI;5&P}ub5^Fy?XkBx9deouiv&@j%yZP%`r^Q- zOz^jFiXQumCFReep$)F8uAXjj+)QsX2J|CXb3j$qb!f_=jZtEHp=+ZWWD#{0s_$$4 zvuGYus@MN+C5LiO^Pq?vdQ>oElkHLlS}q9*>(S3@{esVr6+pQSQ${XP;aQSW&H4?n zoYH|9L#0=lJ$6fqRo8ulr~dv$)rio8BreA|LtsI5Op}x9%dT~MD^G$kbZMnB0hte* z$2^?RNB{QvL!+2bd0-j@L^zd0eZb$<{T|<~POU5ZW06D4V zq^el(aqV3&Dxj?W)lM^?8IYPI?w!b%I_0(6D?p(b1JAScYiAzEB|ncp=&K%i#71y z5kavvQ6topm>KL(?ZR>_m_pf%5{MWi@37RSyz#j`g7K;M80y3Ez^ zj>H#i8v2DGVR$XP-FI1Fj9vv z5tqd`F_S46cXV?>j>BL1)FSQ8kv(xu6t?R^+5Oo7jOIDK0IlHtin8(bOl-r(@o>xq zHMNZTJ>#dq4Bb5ZHOWhc-dauJQB%yPJrT|~bdYcB`zQA68!`HKWiKQUduODmr^siYr#3zcN5nY(swA|3Xf`^G3$;=2!Bp4}-$aILY35hk^kr)bwQtI6ctLn9A$B6~&3 znFZ6(&7buK7S?EiDPXHuM9pT+l9;ju@_z{x)llqeN zIrwx(9cT$RZd6-&NubIBb21YGLH2^6n`@hD5JOmi;9XqgMro&0$bhF1{X^?F4W0F; zCK@U;!hSBG{`EOW-JH+Lih=y<%Q1te&u1`vJ7U@>pNbE9-&&wxtGpxec4~j+E+)Nd zhV6M5C6iZ|I}<75m4OJEHfu_86X_0Fp-)J600%~6#*ZHS`*=II88dHzai^N5L4{dA z?TUH`)Sj@P&-D_WQF7>m;h--iQj1oYe6J#ZoUG=%Ij-K|Tg>QddnhDZzL`BI8=trY zdznfXrhi#_s8Oq(7GcX2u?0wtM#$b&PlIC4p*% zk4FKYYll0w43P2y5lhy~eX)e7qDv1Ckr40EAHT*O4s?WI5V5yz)A(>J;A5?f5-oB^;qr3p>2Hp4GQ?c3~p1IVkH8k2moCLB6fUm4S9Dvxg z+~Fcd_&A0}lf4U3S}W9kON$?+K?pKV`-zE8%&&SH7&R7ghYJ+)Y<=!qb2~B4x%yS^s|=5o>uG>cU5f>0b9rYwAcIp_~cv>$m!0 zt6avaD*3WD%Hp~2$p7QPWP)GcmO4_t;p(pICTDXmiWCc*MBkLrgzACO!8gsxx18Ub zI!@2Oe^K8zBn#AoEODy3MdA302~rzU$7tAY$c66W)|w&}O6@{0U9tPr_~NUIh$g@h zu(>*~keU|@Gwn{zEQNwIu$|a1Ck*H z8#kO`sL?{`uNqro@Nb$4)1zh}_^XcanMjf@>=&C7;|!Yl^VcG6Ry$+{I6RLCa}bA2Pg=l+A$l+GLS8>N&^^Fo2>*-mT;&9><-apEDfjwF_~6**o^$ zo9Cu}hi}ym7@YX=aNL_Afdxr-Mr36{#Tzc=MK3i!)PK18ClL~{1&LGBB$nil(;(8p zZX?N%!5{NovYr|5yqr4+D&?<;m3V}&u(u*MA|chz+;w(}hL+X*P=JtY<;0caZMTkw z&w`oYthdctRu)fOLkxaN>sKB~o1sxeFf=NV_hudy&CIgDG%#}$GlJ;jAA8%Mowg1N z)IgL2T@C+aS%W+kjj82k&oT%sgW3?J{m(#+`1q|=KtF|V=wqln2_T`@;9Os+X>l*y zVN-yjbR1OVFo7%+&7+IT4Ts&;pz#lKnM+r$$by3S;J}>Z{-w*8>tJ3L2BJxsn9e?Y z*so>v>GNk)vjTb%RJixCxY&AYk@acr-Z}xLIX8CILicEw!kmcPaxrc)DYkqV!wok# zR0$hYTU#rhuacrN27)9QJ_?AAJ_iF;c<|MT_uuZwy8L;pg~i&R)<`VA z*PnOTW-Ui5LBHSb1NzsYp&^t8u^cX^0*+4>bV)DHGQM0}vj^RfF$~9}s(;gtcNy*; zAmfBl3M|k#!7|Sa2#|xu{W>~Kq8kUFxiErZ094%opj{O-Q&6#`!AzB!rGQ}CxFQv_ zmk{;v!-+a891N;Dcff{Ti;7du*J$!k2 zd35%Dbc_F3T}S5%f`J91h<@-Pm!o-d*d?)}|qTt$EX%I-mV~h^>HtV65LDjFn@NjX1_>G(K^E9~NC(u}j zvAvt>4<4Lh@xR2yMFH9eBk26YJU)y9(FmHq0S4!`pM!l;kDEu)aw@t4n$j5#C2ThJT>wL&;iH z(joyJ5X$;9f`-DD&7YD zAy62hX{vYlG?Y&D%_nKGW%dT96SxPX1QpZ_xI2%5*P6prti6hzX%7BDL4?a&I#+;^dDOu%` zqxbrg;F*!Bw;CrM7^(-UX`iWtWc}+#eyBrw6_ddSC6FFFc|x$7RXBtg>(I#TT;PhD1jz>mp!TDuHD!ueqbBsCjCxjCuU3T~#_kzK|&m zbON2?H8MJ}SEd6eoSAFOLCD7fqk1rrf`<$Y44_O%9aljmw(-O-Wt28T87&vaM2tD- zm4`-ZJ$9%TWNV8W6Gr40Ox#t^amW(ghH}V9hx`2lNknwl@Zr-Eq7a1;OV%esYp*7(8-&0Jx$#rPA?$v>7qu=JW-LT@~T zHW=5i@N_-e{Zk%QQ6cW(>FLzOta9j^pOq!8rKOb+{s^Y9AzV3?fCX0!pJnxXsFhJa zDcEAil1T~gK5*?i5z`j6i`RKoLP8jKfw{uaebC?kSy&+Yzgn~sr4*I(upuy>0L}1p zoUCs4ix+W0u2(L^!oq?Mf|;7W&%djrM1=ZDiOs0#Zy|Hhn#9)T-UEXFf{rg@PSidi z{{?B?M4}jFZUZLmjevR>D6wHi#z4xc`Pq~h)jWe59rUjT&?dR9tPH#3G%l2o zAjNrL()|`>=SKJv3g~U&^CF<}rxX$rs)q?AFvr`F$I|L(%aniU?|1#hU+#AfvLgxXR&7HYlK*gcm zn;W-o;X=>FZq#$z5R`p_UewhIAZs2N984)Kjj8gLB~JeFgx`JQ@_`)>-rM(bASHNt z-bOy#Se3qeXtWj7-{=%hc(`&x^pm!4-%#okrt8w<^cFNAdV;VKMwuNF9(qH}LO#6wbjsll2WpVWLCv!S5yd`b~PB zE%&*M(6TbAAfTbQPiOA7TVD0{Dx>!`7khj29@jJQSsplyi6u31RX<>Rn@P+*UgbZj zE0q`8fQ%rj|54L&be(pgb$pr0wplh+Lk{29#W|tjZ7I=LliJsr`v#i*{dl(E+!-={>9!Fwq>IsyT zeNY6ba(#l{ZuKwyL)@LE8h6`icUA$K%Vik@k&cX@N4w;HyhMfG&uF+XXXi;5E>b&x zJoi%J&@-JF#?_uzi@MUvAZ+CoDUorZJ$72x0W#**LVH~E%T*wm>iN9GJXu)%UW1m6 znIazxF%8@wO%W741t|3Twu2G1-l!cNLTZ=9tLK*d83-YaRv#pTlx_l`TV#@>t9tBy zp(;K%%jGhL$_-s?AcW5S!a8Og% z^0F^7pw&JTa}BM3k0kJ|WuO|{Xdkp_iYaG53u>d&F3xq)6MMA-80H780uuA#y0>Cw zLi3k|pr7(!PQ;2}n-k_Q5Zl51!w+0Mc!O7xy~h3evKO=|@z_S}#E_k@Ds7fyjT5QyA{Sc@j;_&1@_1fVFVM$OGz3?iG)O> zA{9lVfuu+j(I8EvG|-HSGL$5Z8dZ{18a0SWlqQXa=E+o=yyv}Q@BRDj@Av)ZJ>Grn zKlVOkwbrwq`+n~0ygui7F-xgjp{0b&y+!rymj;?k45pD+H+@v--bE`oVZbl5qJHm+WvqC7~X zBeA^x_F@QG<+JUX*&lZ@zeJg;$69xs!LJj>nA9T8XOU=Zj0l(;5-(+gP+2Fw&-H3)i-HYzJPb zF?r(C)fc+f42;eW+q}r4Wt)d@VfnWzEZXUVv_6zdf9DcU;bFMBmqUyYEeta;_FZki zh|)AA!GLR|^RZT2UfS}*%A_3Hkns~Ct)J6hi*~hW z>}1;1fFyuFC+FPKQ@bv&Wf@Kg7%uf4NFcZJHOYGBug>LP0=G!7mqYIkbZ3fgO4jFI zUP?)}`pkrNpayyI1YnixmP+z%<&~s&Z8mSX#$^=#0Bs(y}pC^)k#iqCu8eCx1N2k5tT$8l2%!~o|FOg&;RTTFY0 zgRhBy5hL&+BAxW9(x4AgzfBG~Z zb$8R0vb6<`1eD2j^zb`d7(&1kX)Sll=1^> zRL{9`8#_Udu*Bn~f1H%ktO`1r2zQu6bgJhLw5LE2*-p+VVvC!O20tD#jBkqtm4j z&jPY))t1w3I{QFgxW8JP7pVwAN10N3W~R<~F+CAfbiA+$3+)>x7B1m|*QVjg6j(Lo zLZI6u=lp917ge@562Rtrm;!s-MZAj+(zX@(b()4UTKV)3%BzvyDDNqSyytA7|Kx)qCa_b@kS%7=Q2Kg-H8t$See`d_u7L zcU&ySzKQF!g!JAK#P_SeFF2%fj^srbZ^6DKE}<~&H$20&-c~AT0| z^@7J{)oUE7G$A)%`<)C4U#E#O63WoOfUz>mC|8M@QC{%;cRKsnou(ZH) z^f>?BZ1uX08y6#)?t-r`gCC~|hqd*iS88Mj^QENJD`%IBrV zOd>=9ETCI`y#6B3{P~FYa$4IQFuZ?D-h4s{+&DzDR+H7{@*vait;Y*U(P32G%=6}@ z*#9EARmYC`A$5ej5b@-1JhKK_G|skoEJ?eJnvtjj1Q3L)xXF_f|Ltgq%ELXt>;)qgaEu~oMgp5(r0kI-;R486 zJddx7VupS_@QD)83pA94YfXs(Wu0BSa$6uH31o$DW-d=-D7S-@JV@kYp)9%iVhp?% zF-W5JwW-#z{pz6@76fEl!RXeUz^+Tz0D%lHJz_s5{u$75U2r2BepA*hd+|z*uI|to)tKxjXFHMhWlb>2)}w8s;qSmAD;<~-%Cu4 zeey&QArARd7BY+A_kp3EnWEr6xq-4|$r9DZN<_)RmL=Ol02&B0jh{a&**%JJLw<`q zQ!0*n?B9G7R#qA2@_nDxw*A9x6>Ov|QBdGl_hZ`v?;>JdXI=M^G~Xj{;p-Kr(V>4TN2`3*Vy0LYC2gwqIcWz1JT&7b9-;iT-^Q;hamcDgsr*k;t5ryG z1}Z5GPo=o|o9{~OTd@ElbF%%i{DnAF5Eorm{r}?5CnFIjLhiTOsgb9Mt$GJd$Te5Y zC&|8;OD%UNLg9?tugIwd2tXf#tb<~;?<7$`I#lUk=xAg@Ts6<6b7!@4`p&563vb@& zg9~aEKHrvtT&pvc@6t7oe(&-Rx)q9s>YFnxP0_bm*PAOE>ac7fwN4g{zaBH+_Yof| z45uV%U<_AO6v_#pCi1@!hv_L$;F8B4L&-c?+WQxR)%qyUSqSK7{!!?d znzca>zpAyhHBg}TAIyW%K=-ncA&M+Q8WLnd=|o1I8g@LAgGt=0u+*i0SAd5%JYq~o zeH_(tuE(x2bT*|!UyL?9F5++TZM-Y?MiV(^$+Gtj!L*32&v_is6_I^hkgD1B>60%u z(uD|e!KTGP0n%uO*hLqxI3xlPp~>d|*{SG-z`Zy`0}&Do`4DjfN8<}_hU@u|9+uXc zraAv-L8nNp51`%<6b-ryuf9Cu3Z zSfu@0#SS{TI;?O^clQ~bHPW>9rVqn0&Jf97AG&Ov#kd)bw(f@F{YwRm(n0q!UukLh)84D@%ld>+yS3Bu0=MJ zL`rSS=8WEp#qd#7c84Sdjlq5I?_XuxTJIdx=^6Us6Fi?L29+`{@;x(dnFSj!6&t3t z3ztOVJ|o8cLx(z!6$i+LJW7g@6WLvLVI;MO%MC^gm%}a+=#}ND_{~Py^tK+li8B`4 z%*Q3Dilb`T(F1nFyA;|mM>|Pygo_t`F({Lr?(y&Mw)@=q$A1AKCfDD9h#dVNYq~S8 zr;h8N(wOYcjURA1Yc1+Sfi2Ff@fSh~>=9gE|Ik4@HS@d1_lHW3WoJ9vTCyndh96#6 zC@UAQB*)<1qM@-@aVqd2a_3yxt9f5F`JL#qR+_^_t@VqYiYXYl< zhd%{}-07X;WAwCPMHE$9PHmWnFm>3%vGK-@Wzp6EqcgO7C0CafJnp=7kBA(02SsCV zJQy|-cz#^~_0kpvi55Ga#|y;^Pj4!q58EfA3GriAC~EX&`I2yfueRD6_4?0wtlW28BEUHLjJe7@L^ZYIWV@)IWR<(MA>$|J4R|C83n5#z89Q(5B*r}fRd^B zr1?a~cGtMy{tM6+zx@}(r-}bUR7MLM<~Cyw2Ep{5>((SzAr0H!<&@Gtv-!4t+F4QL9hHz-fTJlX$)1_9pk^Y>OZ;rR zGD}7fiiA)->xV9V1@wZCuP{0C;Gx4ot<`blWotQ<{8Q`MiVG20f^Qio$<<+DRSoqq zTs7Jfynf=-PPv^yA16-hOP9?VAfI)jTi!M`z9)ce)~xC#;7E*b!&7m3`QfVMolqht ztj>wB^$ij>N!0u16+NH0l|Qi)OH+9o-Sv1kt9LM;=R7T8uD(;iLZ7uypMQWv%iN0Cb_mj6Nf)q`J@fWaS!HYJ}a772odnnUUAh2@QvVXYAiWHQeKTb(v z*_TEgeEs4rxn*hbUb9;qe<+zYpB7M~;8aqHhW+_DaE*Irb#DB;)?F5~lw+Kv!pm8} z=T&dRVfw7%Yvk@NalB|L1?CF(l|rl3s?~sp6XlWn#-?R8jhJXquSQ-wAdhOLBA8oq z0kKlaQ>|1QlkrJvfmE^5@#*y0D<@U)!(rObR;ZP?D6FVAW*g|gSX;$d763)%YWw~( zQtZ4t*z@ySmpr+YT5q4kfc<2-^O{up+O&&X^Yp!GJa!q$#jM>K^ivMkLmn=ocY+19 zcPDEO{g_?EHyn{%9sltLF#=!PlU$eUtzx)|=g&IU6T)VxspmVd=#`<%<9!>GKj^aJ zO6!RJ4H0v4&aLD1gmdH86Ix)!ZaD3}H__66!ah8h1~ zOp4NX{~GAj2R{^E9sNV6LJTDbZ0rjBhxPIO>M;eE|K*QuXO~s?Uvt=D!@)@*--O} zcr%|bv0aF`sC?rM)($jBX+`DE?hRtVJe)KkyiWH?6@?Tt62&8A#2Ys@^`f&cfLVYn z-y2xIr=Y=I5k?iCEACSQwycRik|Tm`!p4TO?c1rFf-C4V!`_tL$-Gi=%^J zgV1i@Q)RlMvF|=dl1@ndQ=!@Ww;xysett zmoLt+(e~jg`8eAi{>yCPZ>d9X*(aFlTdQ}HMu6ayrYw}LC`is@Wj9=oGmKhXk>FE# z<4vT>RlIXz2SDH@X>nor4r(F#Q5x2l*S4IRFBw#l)IKy?%JW;Pvcoe{OlK|;Yrz-w)-%|}*94Bu1Aq-;3V^I(Vc zS*Vn&WC^U3Q8n%x$lbw*uXZmU#1MV4$@ov%ui$J5baSP<5o$tpE9)n0%gm+w$8xPx zX%dVK28N=fWYTp=rFFZI|2LRM>8?|;)OG*DQgH$${^l=Q-y0&25us8z1a1ZoTC z^IJ14NA?^#nCKL5Z#=_+xfW17E+GFah$Ife-Jp){WLX(%-+fa`kHp2rNd(v)NnRi| z==vL{>YP3;htM>7xC9PQmmDsJzg}13 z$l;3>2I7MkQ$tWn;Nho!Eco1G7zt3{ctH8r^j9))1d050csVl7;*M+oN>mF2?ltM) z5*R3Y2M)aNtkP}UAdv22ul>fbXH#zOFU7rC=9<_k_6v)dLp!&biv^Z zM7N#LMG!(@Py}IA4knC5hNF%AR%Q8$6Gy@fq}nVucyUHTph6IL1gpI&dw$o-D=E8 z!IA*zP%h#*t!Fs}_~aretF{g#JKvLrKDWv+?QzeQdIjTjL#c_`htyB>xO3r{+Z*TP zW!PKl=XX@2fluqz^x)_v1nHJRb4)vsr=NS^{{eKmoh~~Vwkv^`H1k=C8HxigUvMD1 zd&-FWfsyS?NZ>I@r_SMFj=TA-9?z~Uh3Dpe_6#z+$t0Mz4pd(n5Sb9`*|)s+UcBFL z>N&B=>6t}I&u)fpu!&?ry^YWSD` zllKRDUdq{4JSeW6c2C>w_G(ZyNZ*o%B&(630yT%s%*?zuD-#R=FN-+90b7U6ZXdqI7n4>c){k+LQZ{Ed@vbp|tj` za=G`Pwzmtz0pFOoCfzpLsmpcctinyYh_uNEb{au?mNXD1<|XK#ZRPBWBDXBegjMTn zl@077|E8P1SZO%rH~a-`$7<%A+b|#6E&66R_5^}XAqpQ=C==qjQqOEBnvyS9{?Wf6 zBy~VY{cl=+Y=aC-SMv^!=E%&Q$y-)YQBs zuh*>UZNBr?P47d)e#&zT8G0tB#tAQ)29djwBANMQZp}o;uUY>?9zPjC)aXQB>wh@4 zQ_i%_RAr6hbBYL#6hklVw`$l{Ay;h-Ze|ikNgUCTjBt(gjEtE7|HNCxzn@-y)j;2O zNFwD@YqR>W?NlS(Kijgwt7 z=w*;M56H<36L4@-Yz3)FqITPo$3Zqy3CxZMM_C~$lG#?~D!Y}(=#k&uuH47olvPid z;@?N8Ocy7+XP@8_(<)AG=x<#E$`d0nHj)7rNDFi7uV+b2Oq6XwWEGJa|K@NX0q}foUH@*+45NYEv?oX0uA9>|?TGK$XGS2B=hu51+Bs71 z`IWr+7A*7_#~DUQ@kVFkCna}h`w`Kks82YHV#9zGpLLrg8PQO7vd=D^JQ0IH7t&sW zoHQh{{_4IIFaIb-VOAT`2BI^f^yfX%X8=j^+f|gcRAvE(VIpuq`~?=OYLbBCC)+Ty zf%$NLU;Eg>_$r)ri6Qo;-L<&FLI$~ABTV}iJ5uXE*2$kvd;rwDERJ5hr>3MO(Sl@Fta4S?32E zaUwog9rnCkTbl4*rYU@pxjtz&>n<*%)vaAoFHm!NQy__vFh6z~PO8@xZQH1azA_&! zqtibigGj42?mh#aQY|845&?woJ~oUvxAql5WgGI&lhEcsuG{|{Izq1^lr61 zs>|u_2t9A#Y$Ys35q~(XD_QjZ44|zaaVpYsP1*$P5X-USFdUy%d7ml-2mzaZizHsP zd9-owxy+5oEBh6*CS18hvjyEUvAl=V4%4?Gow(dE|CO{Ti*l{xkF%&V@02HkTM(K6 zM26`F=RrS13fj5wcI=|t_R^ohjCJahliX*!-SoQd`=ie;Q_?1H^IPfnZplG~2o}m9 z|J`F%w3!UVRD=@v^~L_PQKUwkOQ_L^XNnCz;HMwAH7R77n!6&Wlq`%Bt3Mh&XRo=q zi6O_Z69<6lkug(j8!(&c8r?5X{LlwbrVAC_%Mko_g$TodXGo}noThq4{+yB=Wg7{p z(b!{)sHh}etJhDT@=?=7{Mjh1CC5(xCr{DMsDOYJ_*sqI1|^A=YO|+MEMMu4_(cbw zul$FjC@p*e+j?`tej_dlAwGVj{>nG%Dit0^F-liTn;8-R=_VBe!wMcc;lI~F&Ft`V z$U*_LuyT77pC_ZNb%2OJlisDnG)-&|E=sQRI4T8Mq__K+x3hsd;?tRyN`)x z?4jY@=%~!sgtoo~lp(n+5OXjERsaNp|L(B5#R|c+oz(isbz4H+k)JXBFN$8y)nDQU zFS-iSS$J=(TDP)a;r{y-R9hfSKdC{aO&XxZIdePQx29|d65hI#uW*nL@RT+)@S0(= z^x2p82cE6;O${PESn1PtHL|$k{h>)v?;~|-2&ajA_;-m4Dbj|bg_Bt zcy=M{fS=v+ZxyPZmeeoz&PLo+#cO(=8j&6lX}d9AW-wa@UG~*|$ENu=Y4X@6y8Bew zMm|%KC@Z+LpsC8|+qu13uq71p=(M6|?75Nmz(6@Sp<#Eqe`u-g5^QL^=z5xs{5*g| zcFj@`a>=nWxQi6SFJ}DMCsJ7Wbwt=jW^VP?8^6CjKGJ161a4rpy?~696lL-8zuZKG zyW=-Zr`NYC1#@bSEjyN*G6VTC1_T@NZ#Zq~>-4%7Fclyu4+jby*5mE zqkeJeT1dXqwR*_>-CiS;v*(idObKnKu%^Mu&gLLOa!zl2P4~;~$wJutM6Iror?${; zCQ1!Q&*)OJ+YX%Swt}N4ia2@#hEGm>tfuf+la7eq2Q(pgp?A8vG#$~hTnN^vFO%|w z`T+h-aymOy?)xxRQXa6Dc%XKjxIWK1#1woC%Xm+QR{TDr=IN&pn#n_7-&Y`JQ?Svx zmHfXs&RE0a<~B+@QtEqqkNAQ_(-!hiV&wDkEcn~);dM_4-CaN5mDG3s1Wc5kCg?OG zpGb?o*(gP!K|tF-trm%YtQN>!vfUUF2n#Q9@_le`A+OHoy_VvrohrRfk`E5ey1Hh> zJeHZ+osgtH>k{Cen~RxR@;J~D>ScB02^N=_vADuu1}qF&A_|V_ z{E%J=c4jBBiu!P0H9nOm2(h@d@;!gpq#Jqvri}Y2h5!Qcy2QHg^TAX?wdE6Z7~4tG zbslhJrD$4woZXc9soE#LiY~GU|DTTbpwa9%e#sXm-6*j=AzJatq0J zDe)}Y>>U-jpG3j^EMLMl>PUU`=5T}i&3Wg1UYUNN5>Z zzellt2WR5ml}?;y_2t6cR%VoBbqGAAXJl-*r-nkKa8_1UCc|a<7j2hkdh>>E<;3L3 zx!J5?oLiwC%=5>k@a_VLxiq4nJ08vSVh44U0Nw@ zI!N|^-+F%#11D86DhM-Of-oz386v!qt*;}Tzx17O;RUd46pGPk#(knxhYI4!9#qgA zBKxjk@uwzdB~}tr>KS%FGD-3O%Bz@IPN6<~g2^IHg>LdBOA28(T}ZK*fY<2O>T~V{ zI87(OsVRRu3z9B#TwrSqH8dYLKl6cTwDZuPV9j@Hl52Jiyk%0z&`BE7$aKZgo{nI!%ozMZp}-ZlGg2^nQe$1SpsD5-Wa_O7hwR&>c+rFW_Fo~w5@j{aY(5mm*1N3uP5ls&I!SQ+9Wn0X0_7!4!u5ABVb|j zzr`aCt_6BS@he`EupuTEZ|Fu@v0{Z+j`Ps@EQHlS4;w!Nxaq^2Ur!N0bf-g*6XzD3 z#JXlvGAK^~Y9zms+&uSQ39IHknLN2vBWQ}K2hJ*q_ka94(2>r! z)|3rlOl>a_S7P7ys}%7XB0+sYdWEfj^RhB~=3cYEUcQC=P;B;V7#ile949l4`1>6 z`uNm07h#S9BE2)duKOb&6zrQ`GM~E+m-&`?v_^bJ|Bz%P1~!l(7l;C*G*}u`R8=j5 z@sg5xyiT+xQhs-%$Mb6|AG>~+#1sdPyRK@zh$1#aVfiv58oSJ{Gc6(9iyr*fniR?q zh4LqRr6buuBF!Y1Bm3CPGLnZ5qDN!fHj;2Fy8Zo$&D$)VS#-bSevtcj(Kw(SHg1UJ z1Xaox{widx3Gn_8M1uQjdCT)N4!F_fbFL3bJT>f?nt0Sm%SgfeEa;)K6M?9up?zi) zXm3Z=R*su?nGC)1!5er^|F7Y0|9waifMERizh)S{AKS5Hb>HW`eaO8L+oh(VAzyrH zi-K9up$aVMbnU@CjQc3r{Gq~dSkmge?~YPDu1?4A{Waj= znZ<)`n~Na%0)xVYOX()oGhbypttq3jlnDXK_^bdXo#QnSV)X2jpZt+t)A8*ZlXuC; zgYT5*pB#`q-u~4U$>;1pSbr@qVm!xADPp7?qU&rorBfgLS&*FkW4nfa>VTt-i@y^p z5)IM|Lr?eW`4a{VcM*tCN(^K3 zSXsIG_!zN-jR*eaRK9Vs<0B{(2$S@XvS1M&7?!`*NRqcPlvM+)6q!N;<8JTgmFs;P zRbfnqrHmMpb93c^C+eEtdGu&P0OR$@Xei{3lM$*}X~~b||3!&@ZV?m>y>)!qf_c73 z^7A3GGypChO#0|X4B8bX!!R@+=0nquh0VCEwstqXs24GGPAeA^RW&ipNXM!7^%i32 zB7cA}$BC6n^XJd^Nli_~h#G$YN_<%N-5Ahj*QawrX6=(vSZ7hSIgKxRK9G6h?Q#ru zSdGzLTM+_>-C+U7IL%k%ue2s6sk#_-rn(|`H!@PQtFvC-mNhi& zrC@3`MtbO)pEa-@!OSW#-0B!16^_w&shHTsgDqVQD`nS$#+U7 zd0sO!n2*i^TLFeS`*5l4yraAykI#!p1A~f>aWo4d2a(C(r`7l&5=H=A^}9nxvyUM}zg zj>e69L1~O-o~AT+2)=@ZHKfB>;xG{ElsRnNZq^7?o)SJhQ;d0qt}`7 zFP<=Olf2I5vuB^;7ty3hw#%Zik$3N&)VOdmpGA9;(|5zgQ!5{c6~4B}>XVG9e)Q<; z^qR7+TfVRBqkGP6&W!w8B-}CbRB=M4cIpmh)2zFyb!w<3=Lra1D> zTctm&=C{VfZ>Zo^dy6`9TKLRY~(ON zAnozFmey7hbzk4uXerpZgJbQXB8`Iwg-E_6IuxClao{pOEJPWyc-_<#Fg$$n+~hZu zH2n>$CT2V~Y}jyox%d9Ol-%NCkzM!Je{j~z?m2KGf_W+5Hr`9Bv2`ov2hwBZuMb{` z;V1J0rQRm-VTdXlhU^8x%2@WvAtpC>A!XLsO>F-8W}8Y(C7f-t6z?4vcna^ow6ye< z200V|TaLO57-Dpp zC`goe5KGUN@6;_LfXY;|m4%4FztfzX(X zpn-vb=ipb*@!q;+=cXsP>FDT2T?_Fqzp$`hZI5^305*+v6z871$hFUI);)MIYD_cl z(IdX|s;WGVwA;y`0ubfuj*jcGQ0kC~keImK$;s)ssCS;j-i)@BwMv=_g0Cio)R>+1 zD(H3Zy^TppnYSr=?T5#B_0}QNM7>YD&_ctkA!!AL0E~Vy#}3*jckeArYQrr(H)UZ> z#82k`NJ){TJnLPrtbAEZ?7@*Q_6mX|p{{#O;Yb!g{#~$ji{y1RDZZzOl#{)R*R4c< zv@+|I0$XZBN}x5q!ll9?mP6i_Sw`^U#s#u{e!jO5yJgwLghFLi)m!&-n?%?c>F^P5 z#x7V|u5S`svHa5g)YMDIvLmpr#J3{~9rvOZ~w3NJVeE-30 z^ZUIe@p29>6QfJ_r5jhEeSB4niILH0&z|xhKTe0XJiB}UelSihY>eJwo=45Hn_WKF zEDG&^Vdm<3>%6KLa8U_L`(t}={CC%>aEp`uGe5sd;HIwm{Q21O`7D^Vc^!>l3j>3< z59+0SjLxM*P(m$COcn=iTXyNvr3lP6%91VHaZH;3O=QWd8BBMJ`j}yRSXmfDZ@)}R9DLEt#co{R=VWu@#P*TE zd%kRV+!+}ds27^n#>R^FJ1NO+*l-H(Iet>6x34c^eAdp|dRat)>x{={dE1t9jEShT zkjZ-V=ms`#ZNqz9M^5xTJ9~%2v{dve^M%qSJG8ZB#|7fdqyz9h9L7L%BMcIH;*MW( zW#@7|L&F$;>m&T^Xx9{Fx3AlFRP~4h5MUJ&D>({4`bHJ&|us> kM%nX6py7`{IbP%0`g%-7?3_3|1^;Z{x=Z7}n%RZ_1LZoB)&Kwi 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']: