Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit041c598

Browse files
committed
Use SubplotSpec.row/colspans more, and deprecate get_rows_columns.
1 parent071da48 commit041c598

File tree

4 files changed

+150
-205
lines changed

4 files changed

+150
-205
lines changed

‎doc/api/next_api_changes/deprecations.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,8 @@ In :mod:`mpl_toolkits.axes_grid1.axes_rgb`, ``imshow_rgb`` is deprecated (use
333333
``ax.imshow(np.dstack([r, g, b]))`` instead); ``RGBAxesBase`` is deprecated
334334
(use ``RGBAxes`` instead); ``RGBAxes.add_RGB_to_figure`` is deprecated (it was
335335
an internal helper).
336+
337+
``SubplotSpec.get_rows_columns``
338+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
339+
This method is deprecated. Use the ``GridSpec.nrows``, ``GridSpec.ncols``,
340+
``SubplotSpec.rowspan``, and ``SubplotSpec.colspan`` properties instead.

‎lib/matplotlib/_constrained_layout.py

Lines changed: 122 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,8 @@
5555
_log=logging.getLogger(__name__)
5656

5757

58-
def_in_same_column(colnum0min,colnum0max,colnumCmin,colnumCmax):
59-
return (colnumCmin<=colnum0min<=colnumCmax
60-
orcolnumCmin<=colnum0max<=colnumCmax)
61-
62-
63-
def_in_same_row(rownum0min,rownum0max,rownumCmin,rownumCmax):
64-
return (rownumCmin<=rownum0min<=rownumCmax
65-
orrownumCmin<=rownum0max<=rownumCmax)
58+
def_spans_overlap(span0,span1):
59+
returnspan0.startinspan1orspan1.startinspan0
6660

6761

6862
def_axes_all_finite_sized(fig):
@@ -155,7 +149,7 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
155149
# fill in any empty gridspec slots w/ ghost axes...
156150
_make_ghost_gridspec_slots(fig,gs)
157151

158-
fornnninrange(2):
152+
for_inrange(2):
159153
# do the algorithm twice. This has to be done because decorators
160154
# change size after the first re-position (i.e. x/yticklabels get
161155
# larger/smaller). This second reposition tends to be much milder,
@@ -329,131 +323,110 @@ def _align_spines(fig, gs):
329323
if (hasattr(ax,'get_subplotspec')
330324
andax._layoutboxisnotNone
331325
andax.get_subplotspec().get_gridspec()==gs)]
332-
rownummin=np.zeros(len(axs),dtype=np.int8)
333-
rownummax=np.zeros(len(axs),dtype=np.int8)
334-
colnummin=np.zeros(len(axs),dtype=np.int8)
335-
colnummax=np.zeros(len(axs),dtype=np.int8)
336-
width=np.zeros(len(axs))
337-
height=np.zeros(len(axs))
326+
rowspans= []
327+
colspans= []
328+
heights= []
329+
widths= []
338330

339331
forn,axinenumerate(axs):
340332
ss0=ax.get_subplotspec()
341-
rownummin[n],colnummin[n]=divmod(ss0.num1,ncols)
342-
rownummax[n],colnummax[n]=divmod(ss0.num2,ncols)
343-
width[n]=np.sum(
344-
width_ratios[colnummin[n]:(colnummax[n]+1)])
345-
height[n]=np.sum(
346-
height_ratios[rownummin[n]:(rownummax[n]+1)])
347-
348-
fornn,axinenumerate(axs[:-1]):
349-
# now compare ax to all the axs:
350-
#
351-
# If the subplotspecs have the same colnumXmax, then line
352-
# up their right sides. If they have the same min, then
353-
# line up their left sides (and vertical equivalents).
354-
rownum0min,colnum0min=rownummin[nn],colnummin[nn]
355-
rownum0max,colnum0max=rownummax[nn],colnummax[nn]
356-
width0,height0=width[nn],height[nn]
333+
rowspan=ss0.rowspan
334+
colspan=ss0.colspan
335+
rowspans.append(rowspan)
336+
colspans.append(colspan)
337+
heights.append(sum(height_ratios[rowspan.start:rowspan.stop]))
338+
widths.append(sum(width_ratios[colspan.start:colspan.stop]))
339+
340+
foridx0,ax0inenumerate(axs):
341+
# Compare ax to all other axs: If the subplotspecs start (/stop) at
342+
# the same column, then line up their left (/right) sides; likewise
343+
# for rows/top/bottom.
344+
rowspan0=rowspans[idx0]
345+
colspan0=colspans[idx0]
346+
height0=heights[idx0]
347+
width0=widths[idx0]
357348
alignleft=False
358349
alignright=False
359350
alignbot=False
360351
aligntop=False
361352
alignheight=False
362353
alignwidth=False
363-
formminrange(nn+1,len(axs)):
364-
axc=axs[mm]
365-
rownumCmin,colnumCmin=rownummin[mm],colnummin[mm]
366-
rownumCmax,colnumCmax=rownummax[mm],colnummax[mm]
367-
widthC,heightC=width[mm],height[mm]
368-
# Horizontally align axes spines if they have the
369-
# same min or max:
370-
ifnotalignleftandcolnum0min==colnumCmin:
371-
# we want the _poslayoutboxes to line up on left
372-
# side of the axes spines...
373-
layoutbox.align([ax._poslayoutbox,axc._poslayoutbox],
354+
foridx1inrange(idx0+1,len(axs)):
355+
ax1=axs[idx1]
356+
rowspan1=rowspans[idx1]
357+
colspan1=colspans[idx1]
358+
width1=widths[idx1]
359+
height1=heights[idx1]
360+
# Horizontally align axes spines if they have the same min or max:
361+
ifnotalignleftandcolspan0.start==colspan1.start:
362+
_log.debug('same start columns; line up layoutbox lefts')
363+
layoutbox.align([ax0._poslayoutbox,ax1._poslayoutbox],
374364
'left')
375365
alignleft=True
376-
ifnotalignrightandcolnum0max==colnumCmax:
377-
#line upright sides of _poslayoutbox
378-
layoutbox.align([ax._poslayoutbox,axc._poslayoutbox],
366+
ifnotalignrightandcolspan0.stop==colspan1.stop:
367+
_log.debug('same stop columns;line uplayoutbox rights')
368+
layoutbox.align([ax0._poslayoutbox,ax1._poslayoutbox],
379369
'right')
380370
alignright=True
381-
# Vertically align axes spines if they have the
382-
# same min or max:
383-
ifnotaligntopandrownum0min==rownumCmin:
384-
# line up top of _poslayoutbox
385-
_log.debug('rownum0min == rownumCmin')
386-
layoutbox.align([ax._poslayoutbox,axc._poslayoutbox],
371+
# Vertically align axes spines if they have the same min or max:
372+
ifnotaligntopandrowspan0.start==rowspan1.start:
373+
_log.debug('same start rows; line up layoutbox tops')
374+
layoutbox.align([ax0._poslayoutbox,ax1._poslayoutbox],
387375
'top')
388376
aligntop=True
389-
ifnotalignbotandrownum0max==rownumCmax:
390-
# line up bottom of _poslayoutbox
391-
_log.debug('rownum0max == rownumCmax')
392-
layoutbox.align([ax._poslayoutbox,axc._poslayoutbox],
377+
ifnotalignbotandrowspan0.stop==rowspan1.stop:
378+
_log.debug('same stop rows; line up layoutbox bottoms')
379+
layoutbox.align([ax0._poslayoutbox,ax1._poslayoutbox],
393380
'bottom')
394381
alignbot=True
395-
###########
382+
396383
# Now we make the widths and heights of position boxes
397384
# similar. (i.e the spine locations)
398-
# This allows vertically stacked subplots to have
399-
# different sizes if they occupy different amounts
400-
# of the gridspec: i.e.
385+
# This allows vertically stacked subplots to have different sizes
386+
# if they occupy different amounts of the gridspec: i.e.
401387
# gs = gridspec.GridSpec(3, 1)
402388
# ax1 = gs[0, :]
403389
# ax2 = gs[1:, :]
404390
# then drows0 = 1, and drowsC = 2, and ax2
405391
# should be at least twice as large as ax1.
406392
# But it can be more than twice as large because
407393
# it needs less room for the labeling.
408-
#
409-
# For height, this only needs to be done if the
410-
# subplots share a column. For width if they
411-
# share a row.
412-
413-
drowsC= (rownumCmax-rownumCmin+1)
414-
drows0= (rownum0max-rownum0min+1)
415-
dcolsC= (colnumCmax-colnumCmin+1)
416-
dcols0= (colnum0max-colnum0min+1)
417-
418-
ifnotalignheightanddrows0==drowsC:
419-
ax._poslayoutbox.constrain_height(
420-
axc._poslayoutbox.height*height0/heightC)
394+
395+
# For height, this only needs to be done if the subplots share a
396+
# column.
397+
ifnotalignheightandlen(rowspan0)==len(rowspan1):
398+
ax0._poslayoutbox.constrain_height(
399+
ax1._poslayoutbox.height*height0/height1)
421400
alignheight=True
422-
elif_in_same_column(colnum0min,colnum0max,
423-
colnumCmin,colnumCmax):
424-
ifheight0>heightC:
425-
ax._poslayoutbox.constrain_height_min(
426-
axc._poslayoutbox.height*height0/heightC)
401+
elif_spans_overlap(colspan0,colspan1):
402+
ifheight0>height1:
403+
ax0._poslayoutbox.constrain_height_min(
404+
ax1._poslayoutbox.height*height0/height1)
427405
# these constraints stop the smaller axes from
428406
# being allowed to go to zero height...
429-
axc._poslayoutbox.constrain_height_min(
430-
ax._poslayoutbox.height*heightC/
431-
(height0*1.8))
432-
elifheight0<heightC:
433-
axc._poslayoutbox.constrain_height_min(
434-
ax._poslayoutbox.height*heightC/height0)
435-
ax._poslayoutbox.constrain_height_min(
436-
ax._poslayoutbox.height*height0/
437-
(heightC*1.8))
438-
# widths...
439-
ifnotalignwidthanddcols0==dcolsC:
440-
ax._poslayoutbox.constrain_width(
441-
axc._poslayoutbox.width*width0/widthC)
407+
ax1._poslayoutbox.constrain_height_min(
408+
ax0._poslayoutbox.height*height1/ (height0*1.8))
409+
elifheight0<height1:
410+
ax1._poslayoutbox.constrain_height_min(
411+
ax0._poslayoutbox.height*height1/height0)
412+
ax0._poslayoutbox.constrain_height_min(
413+
ax0._poslayoutbox.height*height0/ (height1*1.8))
414+
# For width, if they share a row.
415+
ifnotalignwidthandlen(colspan0)==len(colspan1):
416+
ax0._poslayoutbox.constrain_width(
417+
ax1._poslayoutbox.width*width0/width1)
442418
alignwidth=True
443-
elif_in_same_row(rownum0min,rownum0max,
444-
rownumCmin,rownumCmax):
445-
ifwidth0>widthC:
446-
ax._poslayoutbox.constrain_width_min(
447-
axc._poslayoutbox.width*width0/widthC)
448-
axc._poslayoutbox.constrain_width_min(
449-
ax._poslayoutbox.width*widthC/
450-
(width0*1.8))
451-
elifwidth0<widthC:
452-
axc._poslayoutbox.constrain_width_min(
453-
ax._poslayoutbox.width*widthC/width0)
454-
ax._poslayoutbox.constrain_width_min(
455-
axc._poslayoutbox.width*width0/
456-
(widthC*1.8))
419+
elif_spans_overlap(rowspan0,rowspan1):
420+
ifwidth0>width1:
421+
ax0._poslayoutbox.constrain_width_min(
422+
ax1._poslayoutbox.width*width0/width1)
423+
ax1._poslayoutbox.constrain_width_min(
424+
ax0._poslayoutbox.width*width1/ (width0*1.8))
425+
elifwidth0<width1:
426+
ax1._poslayoutbox.constrain_width_min(
427+
ax0._poslayoutbox.width*width1/width0)
428+
ax0._poslayoutbox.constrain_width_min(
429+
ax1._poslayoutbox.width*width0/ (width1*1.8))
457430

458431

459432
def_arrange_subplotspecs(gs,hspace=0,wspace=0):
@@ -470,34 +443,25 @@ def _arrange_subplotspecs(gs, hspace=0, wspace=0):
470443
forchild0insschildren:
471444
ss0=child0.artist
472445
nrows,ncols=ss0.get_gridspec().get_geometry()
473-
rowNum0min,colNum0min=divmod(ss0.num1,ncols)
474-
rowNum0max,colNum0max=divmod(ss0.num2,ncols)
446+
rowspan0=ss0.rowspan
447+
colspan0=ss0.colspan
475448
sschildren=sschildren[1:]
476-
forchildcinsschildren:
477-
ssc=childc.artist
478-
rowNumCmin,colNumCmin=divmod(ssc.num1,ncols)
479-
rowNumCmax,colNumCmax=divmod(ssc.num2,ncols)
480-
# OK, this tells us the relative layout of ax
481-
# with axc
482-
thepad=wspace/ncols
483-
ifcolNum0max<colNumCmin:
484-
layoutbox.hstack([ss0._layoutbox,ssc._layoutbox],
485-
padding=thepad)
486-
ifcolNumCmax<colNum0min:
487-
layoutbox.hstack([ssc._layoutbox,ss0._layoutbox],
488-
padding=thepad)
489-
490-
####
449+
forchild1insschildren:
450+
ss1=child1.artist
451+
rowspan1=ss1.rowspan
452+
colspan1=ss1.colspan
453+
# OK, this tells us the relative layout of ax with ax1
454+
pad=wspace/ncols
455+
ifcolspan0.stop<=colspan1.start:
456+
layoutbox.hstack([ss0._layoutbox,ss1._layoutbox],padding=pad)
457+
ifcolspan1.stop<=colspan0.start:
458+
layoutbox.hstack([ss1._layoutbox,ss0._layoutbox],padding=pad)
491459
# vertical alignment
492-
thepad=hspace/nrows
493-
ifrowNum0max<rowNumCmin:
494-
layoutbox.vstack([ss0._layoutbox,
495-
ssc._layoutbox],
496-
padding=thepad)
497-
ifrowNumCmax<rowNum0min:
498-
layoutbox.vstack([ssc._layoutbox,
499-
ss0._layoutbox],
500-
padding=thepad)
460+
pad=hspace/nrows
461+
ifrowspan0.stop<=rowspan1.start:
462+
layoutbox.vstack([ss0._layoutbox,ss1._layoutbox],padding=pad)
463+
ifrowspan1.stop<=rowspan0.start:
464+
layoutbox.vstack([ss1._layoutbox,ss0._layoutbox],padding=pad)
501465

502466

503467
deflayoutcolorbarsingle(ax,cax,shrink,aspect,location,pad=0.05):
@@ -560,33 +524,28 @@ def layoutcolorbarsingle(ax, cax, shrink, aspect, location, pad=0.05):
560524

561525

562526
def_getmaxminrowcolumn(axs):
563-
# helper to get the min/max rows and columns of a list of axes.
564-
maxrow=-100000
565-
minrow=1000000
566-
maxax=None
567-
minax=None
568-
maxcol=-100000
569-
mincol=1000000
570-
maxax_col=None
571-
minax_col=None
572-
527+
"""
528+
Find axes covering the first and last rows and columns of a list of axes.
529+
"""
530+
startrow=startcol=np.inf
531+
stoprow=stopcol=-np.inf
532+
startax_row=startax_row=stopax_row=stopax_col=None
573533
foraxinaxs:
574534
subspec=ax.get_subplotspec()
575-
nrows,ncols,row_start,row_stop,col_start,col_stop= \
576-
subspec.get_rows_columns()
577-
ifrow_stop>maxrow:
578-
maxrow=row_stop
579-
maxax=ax
580-
ifrow_start<minrow:
581-
minrow=row_start
582-
minax=ax
583-
ifcol_stop>maxcol:
584-
maxcol=col_stop
585-
maxax_col=ax
586-
ifcol_start<mincol:
587-
mincol=col_start
588-
minax_col=ax
589-
return (minrow,maxrow,minax,maxax,mincol,maxcol,minax_col,maxax_col)
535+
ifsubspec.rowspan.start<startrow:
536+
startrow=subspec.rowspan.start
537+
startax_row=ax
538+
ifsubspec.rowspan.stop>stoprow:
539+
stoprow=subspec.rowspan.stop
540+
stopax_row=ax
541+
ifsubspec.colspan.start<startcol:
542+
startcol=subspec.colspan.start
543+
startax_col=ax
544+
ifsubspec.colspan.stop>stopcol:
545+
stopcol=subspec.colspan.stop
546+
stopax_col=ax
547+
return (startrow,stoprow-1,startax_row,stopax_row,
548+
startcol,stopcol-1,startax_col,stopax_col)
590549

591550

592551
deflayoutcolorbargridspec(parents,cax,shrink,aspect,location,pad=0.05):
@@ -630,18 +589,16 @@ def layoutcolorbargridspec(parents, cax, shrink, aspect, location, pad=0.05):
630589
# Horizontal Layout: need to check all the axes in this gridspec
631590
forchingslb.children:
632591
subspec=ch.artist
633-
nrows,ncols,row_start,row_stop,col_start,col_stop= \
634-
subspec.get_rows_columns()
635592
iflocation=='right':
636-
ifcol_stop<=maxcol:
593+
ifsubspec.colspan.stop-1<=maxcol:
637594
order= [subspec._layoutbox,lb]
638595
# arrange to right of the parents
639-
ifcol_start>maxcol:
596+
elifsubspec.colspan.start>maxcol:
640597
order= [lb,subspec._layoutbox]
641598
eliflocation=='left':
642-
ifcol_start>=mincol:
599+
ifsubspec.colspan.start>=mincol:
643600
order= [lb,subspec._layoutbox]
644-
ifcol_stop<mincol:
601+
elifsubspec.colspan.stop-1<mincol:
645602
order= [subspec._layoutbox,lb]
646603
layoutbox.hstack(order,padding=pad*gslb.width,
647604
strength='strong')
@@ -686,17 +643,15 @@ def layoutcolorbargridspec(parents, cax, shrink, aspect, location, pad=0.05):
686643
# Vertical Layout: need to check all the axes in this gridspec
687644
forchingslb.children:
688645
subspec=ch.artist
689-
nrows,ncols,row_start,row_stop,col_start,col_stop= \
690-
subspec.get_rows_columns()
691646
iflocation=='bottom':
692-
ifrow_stop<=minrow:
647+
ifsubspec.rowspan.stop-1<=minrow:
693648
order= [subspec._layoutbox,lb]
694-
ifrow_start>maxrow:
649+
elifsubspec.rowspan.start>maxrow:
695650
order= [lb,subspec._layoutbox]
696651
eliflocation=='top':
697-
ifrow_stop<minrow:
652+
ifsubspec.rowspan.stop-1<minrow:
698653
order= [subspec._layoutbox,lb]
699-
ifrow_start>=maxrow:
654+
elifsubspec.rowspan.start>=maxrow:
700655
order= [lb,subspec._layoutbox]
701656
layoutbox.vstack(order,padding=pad*gslb.width,
702657
strength='strong')

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp