rL izdZddlZddlZddlmZmZddlm Z ddl m Z ejeZ ddZddZdZdZdZddddd d Zddddd d Zddd d ZdZdZdZddddd dZdddZdZdZy)a Adjust subplot layouts so that there are no overlapping Axes or Axes decorations. All Axes decorations are dealt with (labels, ticks, titles, ticklabels) and some dependent artists are also dealt with (colorbar, suptitle). Layout is done via `~matplotlib.gridspec`, with one constraint per gridspec, so it is possible to have overlapping Axes if the gridspecs overlap (i.e. using `~matplotlib.gridspec.GridSpecFromSubplotSpec`). Axes placed using ``figure.subplots()`` or ``figure.add_subplots()`` will participate in the layout. Axes manually placed via ``figure.add_axes()`` will not. See Tutorial: :ref:`constrainedlayout_guide` General idea: ------------- First, a figure has a gridspec that divides the figure into nrows and ncols, with heights and widths set by ``height_ratios`` and ``width_ratios``, often just set to 1 for an equal grid. Subplotspecs that are derived from this gridspec can contain either a ``SubPanel``, a ``GridSpecFromSubplotSpec``, or an ``Axes``. The ``SubPanel`` and ``GridSpecFromSubplotSpec`` are dealt with recursively and each contain an analogous layout. Each ``GridSpec`` has a ``_layoutgrid`` attached to it. The ``_layoutgrid`` has the same logical layout as the ``GridSpec``. Each row of the grid spec has a top and bottom "margin" and each column has a left and right "margin". The "inner" height of each row is constrained to be the same (or as modified by ``height_ratio``), and the "inner" width of each column is constrained to be the same (as modified by ``width_ratio``), where "inner" is the width or height of each column/row minus the size of the margins. Then the size of the margins for each row and column are determined as the max width of the decorators on each Axes that has decorators in that margin. For instance, a normal Axes would have a left margin that includes the left ticklabels, and the ylabel if it exists. The right margin may include a colorbar, the bottom margin the xaxis decorations, and the top margin the title. With these constraints, the solver then finds appropriate bounds for the columns and rows. It's possible that the margins take up the whole figure, in which case the algorithm is not applied and a warning is raised. See the tutorial :ref:`constrainedlayout_guide` for more discussion of the algorithm with examples. N)_apiartistc J|j}t|d|}|dstjdyt dD]Z} t |||||||t |||||t||||jd} t||rt||||||||rt||}||jt||rt|||||||ntj| |jx} | jrw| jrk| j\} } | j!| ||j#j$|zf| j'd ntj| t)||]|S) a3 Do the constrained_layout. Called at draw time in ``figure.constrained_layout()`` Parameters ---------- fig : `~matplotlib.figure.Figure` `.Figure` instance to do the layout in. h_pad, w_pad : float Padding around the Axes elements in figure-normalized units. hspace, wspace : float Fraction of the figure to dedicate to space between the Axes. These are evenly spread between the gaps between the Axes. A value of 0.2 for a three-column layout would have a space of 0.1 of the figure width between each column. If h/wspace < h/w_pad, then the pads are used instead. rect : tuple of 4 floats Rectangle in figure coordinates to perform constrained layout in [left, bottom, width, height], each from 0-1. compress : bool Whether to shift Axes so that white space in between them is removed. This is useful for simple grids of fixed-aspect Axes (e.g. a grid of images). Returns ------- layoutgrid : private debugging structure N)recthasgridszhThere are no gridspecs with layoutgrids. Possibly did not call parent GridSpec with the "figure" keyword)h_padw_padhspacewspace)r r z{constrained_layout not applied because axes sizes collapsed to zero. Try making figure larger or Axes decorations smaller.bottom) _get_renderermake_layoutgridsr warn_externalrangemake_layout_marginsmake_margin_suptitlesmatch_submerged_marginsupdate_variablescheck_no_collapsed_axesreposition_axescompress_fixed_aspect _suptitle get_in_layout_autopos get_position set_positionget_inner_bboxy1set_verticalalignment reset_margins) figr r r r rcompressrenderer layoutgrids_warn_collapsedsuptitlexs d/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/matplotlib/_constrained_layout.pydo_constrained_layoutr+?sH  "H"348K z " / 0  1X,( Khe"'v Gk3$) + S1 C))+G #; 4 Khe"'v G3KE C 113*;<#Khe*/vO&&~6!$.X; ..0X5F5F#002DAq))K,;;=@@5HIK228<   ~ .k3'Y,(Z c |t}d|d<t|dstj|d||<ns|jj }t ||}||}tj|dddd|jj|jjf ||<|jD]}t||}|jD]!}|j }|t ||}#|S) z Make the layoutgrid tree. (Sub)Figures get a layoutgrid so we can have figure margins. Gridspecs that are attached to Axes get a layoutgrid so Axes can have margins. Fr_parentfiglb)parentnamepanellbT)r0r1 parent_innernrowsncols parent_pos) dicthasattr mlayoutgrid LayoutGrid _subplotspec get_gridspecmake_layoutgrids_gsrowspancolspansubfigsr _localaxes)r"r%rgsparentlbsfigaxs r*rrs f "' J 3 "'11GL C   * * ,*+r: r?&111((00((002 3 C :&t[9 :nn? __  >-k2>K? r,c ||vs |j|Sd|d<t|ds`||j}tj|dd|j|j |j |j||<|S|j}|j}||vr t||}||}|df}||vr3tj|ddd|j|jf||<tj||d|j |j|j |j ||<|S) zR Make the layoutgrid for a gridspec (and anything nested in the gridspec) Tr _subplot_specgridspec)r0r4r1r6r5 width_ratios height_ratiostopr3)r0r1r5r6r7)r0r1r5r6rJrK) figurer9r:r;_ncols_nrowsget_width_ratiosget_height_ratiosrHr=r>r?r@)r%rCr0 subplot_specparentgs subspeclbreps r*r>r>sX  [BII-#K  2 'RYY'%00!iiryy002 224 6 B< +'' ,,. ; &-k8DK) 5k k !*55 q(00,2F2FG  IK  &00"3'iiryy002 224 6 B r,cl|jD]}t||}|ry|jD]}|j}||vs||}t |j D]P}t |j D]6}|j||} | jdks| jdks4yRy)z9 Check that no Axes have collapsed to zero size. FrT) rAraxesr=rr5r6rwidthheight) r%r"rEokrFrClgijbbs r*rrs  $[$ 7hh% __   RB288_ %rxx%A**1a0Bxx1} Q$% % % r,cd}|jD]Y}|j|j|j}|j}|A|}t j |j }t j |j}n||k7r td|jd}|jd} |j| jz } | dkDr0t j|j| ||j<|j| jz } | dkDs*t j|j| ||j<\| tdt jdz } ||j!d| ||j!d | t jdz } ||j!d | ||j!d | |S) NzECannot do compressed layout if Axes are notall from the same gridspecToriginalFrz>Cannot do compressed layout if no Axes are part of a gridspec.rleftrightrLr )rWget_subplotspec apply_aspectr=npzerosr6r5 ValueErrorrrXmaximumr@rYr?sumedit_margin_min)r%r"rCrFsub_gsextrawextrahorigactualdwdhwhs r*rr s BhhF    '    "  :BXXbhh'FXXbhh'F BY:; ;-%0 ZZ&,, & 6"$**VCKK-@""EF3;;  [[6== ( 6"$**VCKK-@""EF3;; )F, z34 4 vA$$VQ/$$Wa0 vA$$UA.$$Xq1 r,r r r r c |j}|j}t|dr5|j |jn|}|j |jn|}n4|j |j n|}|j |j n|}|dz }|dz }|j\} } ||||ddddd} || z |kDrB|jjdkDr|| z | d<|jj| kr|| z | d<|| z |kDrB|jj| kr|| z | d<|jjdkDr|| z | d<| S) Nr rr)leftcbrightcbbottomcbtopcbrbrcrLr rxryrzr{) r<r=r9r r _hspace_wspace get_geometryr@startstopr?) objr r r r ssrCr|r}r5r6margins r*get_margin_from_paddingr0sN  B  Br8 " 52996 " 52996!#!72::V!#!72::VkGkG??$LE5%%!!%F ::  a &F8  ::??U " '%F9  ::??U "!(5F:  ::  a %oF7O Mr,c  |jD]U}|j}|j} t|||||||t |dd||} || j | |W|j D]} | jr| js%| j}|j} | |vryt | ||||} t| |\} }| dxx| j|jz z cc<| dxx|j| jz z cc<| dxx| j|jz z cc<| dxx|j| jz z cc<| jD]}t||}t!|\}}|j"d}t||\}}|dk(r>|j$|j&j$k(r| d xx|j(|zz cc<n|dk(r>|j*|j&j*k(r| d xx|j(|zz cc<n|dk(r>|j*|j,j*k(rX| d xx|j.|zz cc<n=|j$|j,j$k(r| d xx|j.|zz cc<|d vr|j*|j&j*k(r=|j|jkr$| dxx|j|jz z cc<|j$|j&j$k(r=|j|jkDr$| dxx|j|jz z cc<|dvs |j$|j,j$k(r=|j|jkr$| dxx|j|jz z cc<|j*|j,j*k(s|j|jkDs| dxx|j|jz z cc<|| j | ||j0D]}d}|j2s|j4|$|j6j9j:}||j=|}|j(d|zz}|j.d|zz}|j2}|dk(r||j?d|n|dk(r||j?d||dk(r||j?d||dk(s||j?d|y)a For each Axes, make a margin between the *pos* layoutbox and the *axes* layoutbox be a minimum size that can accommodate the decorations on the axis. Then make room for colorbars. Parameters ---------- layoutgrids : dict fig : `~matplotlib.figure.Figure` `.Figure` instance to do the layout in. renderer : `~matplotlib.backend_bases.RendererBase` subclass. The renderer to use. w_pad, h_pad : float, default: 0 Width and height padding (in fraction of figure). hspace, wspace : float, default: 0 Width and height padding as fraction of figure size divided by number of columns or rows. rvrNrbrcr rLlocationryrxr{rz)rLr rbrcrlowerupper) rAr<r=rredit_outer_margin_minsrBrdrget_pos_and_bboxx0x1y0r _colorbarscolorbar_get_padget_cb_parent_spans_colorbar_inforr@rXrr?rYlegends _outside_loc_bbox_to_anchor transFigureinvertedtransform_bbox get_tightbboxrk)r%r"r$r r r r rErrCmarginsrFrposbboxcbaxpad cbp_rspan cbp_cspanloccbposcbbboxleg inv_trans_figrtru legendlocs r*rrVs, <    __ Kx"'u#)& :*$aq17HB..w; <nn>;!!#2+;+;+=     ! __  [ (506vG$R2 T v#&&477**w477SVV++xCFFTWW,,u 366)) MM% 9D";5C#6t#< Iy%%j1C,T8>RZZ__49%);;%??bjj&6&668$ s(::$??bjj&6&667Ov}}s'::O>>RZZ__4:&&--#*==&''OOrzz'7'77 DGG+6Ndgg &99NNNbjjoo5 DGG+7Ovyy477'::O''NNbjjoo5 DGG+8$&))(;;$OOrzz'7'77 DGG+5MVYY%88MK% 9N B..vr:}>;B{{<    3 3 ;$ # 8 8 : I I  !2!28!<=D QY&A a%i'A((IG#C 001=g%C 00:G#C 00!<f$C 00;! ? !>:u 5 NN ' '1{(; < !=!=h!GHD   , ,X-1[[1u9-D F ~~!cnn&B&B&D NN ' ' ) 3>>:u 5 NN ' 'ad(; < !=!=h!GHD   , ,VTZZ!e)5K L 6'E!r,c  g}|jD]}|t||z }|jDcgc](}|j|j r||vr|*}}|D]t}|j}|j |vr|j |8||j }t|jdkDrtj|jd|jdd|jd|jddz} tj|jd|jdd|jd|jddz} |D]} | j} || j } | )t| jdkDsBtj| jd| jdd| jd| jddz}|| kDr|} tj| jd| jdd| jd| jddz}|| kDs|} |jddD]}|jd| ||jddD]}|jd| |t|jdkDsktj|jd |jdd|jd |jddz}tj|jd |jdd|jd |jddz}|D]} | j} || j } | *t| jdkDsCtjtj| jd | jdd| jd | jddz|g}tjtj| jd | jdd| jd | jddz|g}|jddD]}|jd |||jddD]}|jd ||w|Scc}w) a Make the margins that are submerged inside an Axes the same size. This allows Axes that span two columns (or rows) that are offset from one another to have the same size. This gives the proper layout for something like:: fig = plt.figure(constrained_layout=True) axs = fig.subplot_mosaic("AAAB CCDD") Without this routine, the Axes D will be wider than C, because the margin width between the two columns in C has no width by default, whereas the margins between the two columns of D are set by the width of the margin between A and B. However, obviously the user would like C and D to be the same size, so we need to add constraints to these "submerged" margins. This routine makes all the interior margins the same, and the spacing between the three columns in A and the two column in C are all set to the margins between the two columns of D. See test_constrained_layout::test_constrained_layout12 for an example. Nr3rbrxrcry)cellrLr{r rz)rArget_axesrdrr=removelenr@rfmax margin_valsrkr?)r%r"axsdonerEaaxsax1ss1lg1maxsublmaxsubrax2ss2lg2maxsubl2maxsubr2r\maxsubtmaxsubbs r*rrs2G >*;==>lln "  ".1??3D  "C "??!!#    [ 0 JJsO #**,- s{{ a ff' AB8)#++ab/:;Gff(Sb)9: *3;;s+;<=G +))+!#"2"2"45?s3;;'7!';!vv/ AB@1#++ab/BC DH ')"*!vv0Sb1AB 23;;s3CDE FH ')"* +[[_ =##FG!#< =[["% >##GW1#= > s{{ a ff&s{{127(QR9:Gff)#++cr*:; +CKK,<=>G  %))+!#"2"2"45?3;;'!+"$&&"&&OOE23;;qr?COOG4S[[_EF+#*$#%#%&&"&&OOH5ckk#26FGOOJ7 CR8HIJ+#*$#% %[[_ <##E7#; <[["% ?##HgA#> ?}??B JK "s-S ctj}tj }tj}tj }|jdD]}|j}t |j j |}t|j j|}t |jj |}t|jj|}t||}t||}||fS)z Figure out which subplotspecs this colorbar belongs to. Parameters ---------- cbax : `~matplotlib.axes.Axes` Axes for the colorbar. parents) rfinfrrdminr?rrrr@r) rrowstartrowstopcolstartcolstopr0rr?r@s r*rrXsvvHvvgGvvHvvgG%%i00  # # %rzz''2bjjoow/rzz''2bjjoow/ 0Hg&GHg&G G r,c0|jd}|jd}|j|j|jz }t j ||}||}||fS|j|jj}||fS)a{ Get the position and the bbox for the Axes. Parameters ---------- ax : `~matplotlib.axes.Axes` renderer : `~matplotlib.backend_bases.RendererBase` subclass. Returns ------- pos : `~matplotlib.transforms.Bbox` Position in figure coordinates. bbox : `~matplotlib.transforms.Bbox` Tight bounding box in figure coordinates. FrootTr`) get_figurer transformedrrmartist_get_tightbbox_for_layout_onlyr)rFr$r"r tightbboxrs r*rrqs --U- #C //4/ (C //#,,s> ?C66r8DI 9$$S__%=%=%?@ 9r,c |j|jz }|jD]H}||j} |j | j |t |||||||J|jD]} | j| js$| j} | j} | |vry|| j| j| j} |j| } | j| ddddd}t!| j"dddD]*\}}| |j$ddk(st'|||| ,y) zF Reposition all the Axes based on the new inner bounding box. )r)r r r r Nrowscolsr)rbrcr rLrroffset)rrrAget_outer_bbox_redo_transform_rel_figrrrBrdrr=rr?r@r _set_position enumeraterrreposition_colorbar)r%r"r$r r r r trans_fig_to_subfigrErrFrrCnewbboxrnnrs r*rrsv //C,>,>> 64 //1 $$!!"56 % 8 T8#5%f 6 6nn3    'r/?/?/A    ! __  [ 2--2::35::.?&44T: ! a1Q?!"--""56 3HBT((3A66#Kx+13 3-3r,rc|jd}|dj}|jd}|j|jz }t |\}} ||j || } ||j|| } |jd} |jd} |jd}|jd }|jd }t||\}}t||}| d vr| j||j| | }| d k(rn|j|jz }| j|jz |d z}|||zz }|d xx|j|zz cc<|j|d}n|j|jz }| j|jz }||j |z |z|d z z }|d xx|j|zz cc<|j|d}n| j||j| | }| dk(rm|j |j z }| j"|j z |dz}|||zz }|dxx|j$|zz cc<|jd|}nz|j |j z }| j |j z }||j$ |z |z|dz z }|dxx|j$|zz cc<|jd|}|j'|}|j)|j|j+||j-| | dvrd|z }|j/||j1d|S)a Place the colorbar in its new place. Parameters ---------- layoutgrids : dict cbax : `~matplotlib.axes.Axes` Axes for the colorbar. renderer : `~matplotlib.backend_bases.RendererBase` subclass. The renderer to use. offset : array-like Offset the colorbar needs to be pushed to in order to account for multiple colorbars. rrFrrranchorfractionaspectshrinkrrcrbrLr )r rLr3auto)rr=rrrrget_bbox_for_cbrrrshrunkanchoredrrrX translatedrrrYr set_transformr set_anchorset_box_aspect set_aspect)r%rr$rrrCr"r cb_rspans cb_cspans bboxparentpbrrrrrrrcbpadpbcblmargindxbmargindys r*rrsg !!),G  "B //u/ %C//C,>,>>.t4IyR00i6?1AJ R ' 'YY ' GB"":.H   *F"":.H   *F   *F$T84ME6 [$ /E$$yy6*33FB? w hh*G(6'?:B %'/ !B 7Ov||e3 3O??2q)Dhh*G(B 6<<-%''1F6NB BB 6NfllU2 2N??2q)Dyy*33FB? u hh*G(6%=8B %'/ !B 5MV]]U2 2M??1b)Dhh*G(B 6==.5(72VH5EE EB 8   5 5 ??1b)D  - -d 3Ds))*tOOF$$VOOF Mr,c|jD]}t|||jD];}|js|j }||vs)||j=||jy)z Reset the margins in the layoutboxes of *fig*. Margins are usually set as a minimum, so if the figure gets smaller the minimum needs to be zero in order for it to grow again. N)rAr!rWrr=)r%r"rErFrCs r*r!r!sw )k4()hh0   "B[ B--/ 0 ""$r,c|jd}|dj}t|\}}||j||}|jddvr |j}n |j }|jd|zS)Nrrrr)rcrbr)rr=rrrXrY)r%caxrrCrr bboxoutersizes r*rrs  +G  "B.s3IyB..II.NI *%)::   e $t ++r,)NNrrr3r3F)r) __doc__loggingnumpyrf matplotlibrrrmatplotlib.transforms transformsrmatplotlib._layoutgrid _layoutgridr: getLogger__name___logr+rr>rrrrrrrrrrr!rr,r*rs/b.+,w" :F#(Zz*Z+\("J+,1#$Q#L>?a s