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

Commitd443e9d

Browse files
committed
ENH: Support units when specifying the figsize
Reviving the spirit of#12402 and#12415, because both had significant user votes on GitHub.This PR is intentionally minimal to only expand the `figsize` parameter when creating a figure. This should be the most relevant use case. Later changing the figure size or reading it is probably less necessary. The minimal approach removes the need to track and return sizes. It is just an enhanced specification capability which directly parses to the internally used inch unit.
1 parent33dbc47 commitd443e9d

File tree

5 files changed

+94
-6
lines changed

5 files changed

+94
-6
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Figure size units
2+
-----------------
3+
4+
When creating figures, it is now possible to define figure sizes in cm or pixel.
5+
6+
Up to now the figure size is specified via ``plt.figure(..., figsize=(6, 4))``,
7+
and the given numbers are interpreted as inches. It is now possible to add a
8+
unit string to the tuple, i.e. ``plt.figure(..., figsize=(600, 400, "px"))``.
9+
Supported unit strings are "in", "cm", "px".

‎lib/matplotlib/figure.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,8 +2475,13 @@ def __init__(self,
24752475
"""
24762476
Parameters
24772477
----------
2478-
figsize : 2-tuple of floats, default: :rc:`figure.figsize`
2479-
Figure dimension ``(width, height)`` in inches.
2478+
figsize : (float, float) or (float, float, str), default: :rc:`figure.figsize`
2479+
The figure dimensions. This can be
2480+
2481+
- a tuple ``(width, height, unit)``, where *unit* is one of "in" (inch),
2482+
"cm" (centimenter), "px" (pixel).
2483+
- a tuple ``(width, height)``, which is interpreted in inches, i.e. as
2484+
``(width, height, "in")``.
24802485
24812486
dpi : float, default: :rc:`figure.dpi`
24822487
Dots per inch.
@@ -2612,6 +2617,8 @@ def __init__(self,
26122617
edgecolor=mpl._val_or_rc(edgecolor,'figure.edgecolor')
26132618
frameon=mpl._val_or_rc(frameon,'figure.frameon')
26142619

2620+
figsize=_parse_figsize(figsize,dpi)
2621+
26152622
ifnotnp.isfinite(figsize).all()or (np.array(figsize)<0).any():
26162623
raiseValueError('figure size must be positive finite not '
26172624
f'{figsize}')
@@ -3713,3 +3720,46 @@ def figaspect(arg):
37133720
# the min/max dimensions (we don't want figures 10 feet tall!)
37143721
newsize=np.clip(newsize,figsize_min,figsize_max)
37153722
returnnewsize
3723+
3724+
3725+
def_parse_figsize(figsize,dpi):
3726+
"""
3727+
Convert a figsize expression to (width, height) in inches.
3728+
3729+
Parameters
3730+
----------
3731+
figsize : (float, float) or (float, float, str)
3732+
This can be
3733+
3734+
- a tuple ``(width, height, unit)``, where *unit* is one of "in" (inch),
3735+
"cm" (centimenter), "px" (pixel).
3736+
- a tuple ``(width, height)``, which is interpreted in inches, i.e. as
3737+
``(width, height, "in")``.
3738+
3739+
dpi : float
3740+
The dots-per-inch; used for converting 'px' to 'in'.
3741+
"""
3742+
num_parts=len(figsize)
3743+
ifnum_parts==2:
3744+
returnfigsize
3745+
elifnum_parts==3:
3746+
x,y,unit=figsize
3747+
ifunit=='in':
3748+
pass
3749+
elifunit=='cm':
3750+
x/=2.54
3751+
y/=2.54
3752+
elifunit=='px':
3753+
x/=dpi
3754+
y/=dpi
3755+
else:
3756+
raiseValueError(
3757+
f"Invalid unit{unit!r} in 'figsize'; "
3758+
"supported units are 'in', 'cm', 'px'"
3759+
)
3760+
returnx,y
3761+
else:
3762+
raiseValueError(
3763+
"Invalid figsize format, expected (x, y) or (x, y, unit) but got "
3764+
f"{figsize!r}"
3765+
)

‎lib/matplotlib/figure.pyi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,9 @@ class Figure(FigureBase):
318318
subplotpars:SubplotParams
319319
def__init__(
320320
self,
321-
figsize:tuple[float,float]|None= ...,
321+
figsize:tuple[float,float]
322+
|tuple[float,float,Literal["in","cm","px"]]
323+
|None= ...,
322324
dpi:float|None= ...,
323325
*,
324326
facecolor:ColorType|None= ...,
@@ -421,3 +423,8 @@ class Figure(FigureBase):
421423
deffigaspect(
422424
arg:float|ArrayLike,
423425
)->np.ndarray[tuple[Literal[2]],np.dtype[np.float64]]: ...
426+
427+
def_parse_figsize(
428+
figsize:tuple[float,float]|tuple[float,float,Literal["in","cm","px"]],
429+
dpi:float
430+
)->tuple[float,float]: ...

‎lib/matplotlib/pyplot.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,9 @@ def figure(
875875
# autoincrement if None, else integer from 1-N
876876
num:int|str|Figure|SubFigure|None=None,
877877
# defaults to rc figure.figsize
878-
figsize:ArrayLike|None=None,
878+
figsize:ArrayLike# a 2-element ndarray is accepted as well
879+
|tuple[float,float,Literal["in","cm","px"]]
880+
|None=None,
879881
# defaults to rc figure.dpi
880882
dpi:float|None=None,
881883
*,
@@ -908,8 +910,12 @@ def figure(
908910
window title is set to this value. If num is a ``SubFigure``, its
909911
parent ``Figure`` is activated.
910912
911-
figsize : (float, float), default: :rc:`figure.figsize`
912-
Width, height in inches.
913+
figsize : (float, float) or (float, float, str), default: :rc:`figure.figsize`
914+
The figure dimensions. This can be
915+
916+
- a tuple ``(width, height, unit)``, where *unit* is one of "inch", "cm",
917+
"px".
918+
- a tuple ``(x, y)``, which is interpreted as ``(x, y, "inch")``.
913919
914920
dpi : float, default: :rc:`figure.dpi`
915921
The resolution of the figure in dots-per-inch.

‎lib/matplotlib/tests/test_figure.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,3 +1819,19 @@ def test_subfigure_stale_propagation():
18191819
sfig2.stale=True
18201820
assertsfig1.stale
18211821
assertfig.stale
1822+
1823+
1824+
@pytest.mark.parametrize("figsize, figsize_inches", [
1825+
((6,4), (6,4)),
1826+
((6,4,"in"), (6,4)),
1827+
((5.08,2.54,"cm"), (2,1)),
1828+
((600,400,"px"), (6,4)),
1829+
])
1830+
deftest_figsize(figsize,figsize_inches):
1831+
fig=plt.figure(figsize=figsize,dpi=100)
1832+
asserttuple(fig.get_size_inches())==figsize_inches
1833+
1834+
1835+
deftest_figsize_invalid_unit():
1836+
withpytest.raises(ValueError,match="Invalid unit 'um'"):
1837+
plt.figure(figsize=(6,4,"um"))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp