Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ee63e75

Browse files
ENH: Support partial figsize with None
* ENH: Support partial figsize with None (matplotlib#31400) * ENH: disallow None in Figure.set_size_inches * Update lib/matplotlib/figure.py Co-authored-by: Tim Hoffmann <[email protected]> * Update lib/matplotlib/tests/test_figure.py Co-authored-by: Tim Hoffmann <[email protected]> * Update lib/matplotlib/tests/test_figure.py Co-authored-by: Tim Hoffmann <[email protected]> * Update lib/matplotlib/tests/test_figure.py Co-authored-by: Tim Hoffmann <[email protected]> * ENH: parse partial None figsize in _parse_figsize * Simplify set_size_inches argument handling * DOC: document partial None support for figsize * Update doc/release/next_whats_new/partial_figsize_none.rst Co-authored-by: Tim Hoffmann <[email protected]> * Update lib/matplotlib/figure.py Co-authored-by: Tim Hoffmann <[email protected]> * Update lib/matplotlib/pyplot.py Co-authored-by: Tim Hoffmann <[email protected]> --------- Co-authored-by: Tim Hoffmann <[email protected]>
1 parent 7c7e251 commit ee63e75

4 files changed

Lines changed: 61 additions & 6 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Partial ``figsize`` specification at figure creation
2+
----------------------------------------------------
3+
4+
Figure creation now accepts a single ``None`` in ``figsize``.
5+
Passing ``(None, h)`` uses the default width from :rc:`figure.figsize`, and
6+
passing ``(w, None)`` uses the default height.
7+
Passing ``(None, None)`` is invalid and raises a `ValueError`.
8+
9+
For example::
10+
11+
import matplotlib.pyplot as plt
12+
fig = plt.figure(figsize=(None, 4))

lib/matplotlib/figure.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,6 +2492,9 @@ def __init__(self,
24922492
- a tuple ``(width, height)``, which is interpreted in inches, i.e. as
24932493
``(width, height, "in")``.
24942494
2495+
One of *width* or *height* may be ``None``; the respective value is
2496+
taken from :rc:`figure.figsize`.
2497+
24952498
dpi : float, default: :rc:`figure.dpi`
24962499
Dots per inch.
24972500
@@ -3155,6 +3158,10 @@ def set_size_inches(self, w, h=None, forward=True):
31553158
"""
31563159
if h is None: # Got called with a single pair as argument.
31573160
w, h = w
3161+
if w is None or h is None:
3162+
raise ValueError(
3163+
"Figure.set_size_inches does not accept None; provide both "
3164+
"width and height explicitly")
31583165
size = np.array([w, h])
31593166
if not np.isfinite(size).all() or (size < 0).any():
31603167
raise ValueError(f'figure size must be positive finite not {size}')
@@ -3763,25 +3770,40 @@ def _parse_figsize(figsize, dpi):
37633770
"""
37643771
num_parts = len(figsize)
37653772
if num_parts == 2:
3766-
return figsize
3773+
x, y = figsize
37673774
elif num_parts == 3:
37683775
x, y, unit = figsize
37693776
if unit == 'in':
37703777
pass
37713778
elif unit == 'cm':
3772-
x /= 2.54
3773-
y /= 2.54
3779+
if x is not None:
3780+
x /= 2.54
3781+
if y is not None:
3782+
y /= 2.54
37743783
elif unit == 'px':
3775-
x /= dpi
3776-
y /= dpi
3784+
if x is not None:
3785+
x /= dpi
3786+
if y is not None:
3787+
y /= dpi
37773788
else:
37783789
raise ValueError(
37793790
f"Invalid unit {unit!r} in 'figsize'; "
37803791
"supported units are 'in', 'cm', 'px'"
37813792
)
3782-
return x, y
37833793
else:
37843794
raise ValueError(
37853795
"Invalid figsize format, expected (x, y) or (x, y, unit) but got "
37863796
f"{figsize!r}"
37873797
)
3798+
3799+
if x is None and y is None:
3800+
raise ValueError(
3801+
"figsize=(None, None) is invalid; at least one of width or "
3802+
"height must be provided")
3803+
3804+
default_width, default_height = mpl.rcParams["figure.figsize"]
3805+
if x is None:
3806+
x = default_width
3807+
if y is None:
3808+
y = default_height
3809+
return x, y

lib/matplotlib/pyplot.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,9 @@ def figure(
947947
"px".
948948
- a tuple ``(x, y)``, which is interpreted as ``(x, y, "inch")``.
949949
950+
One of *width* or *height* may be ``None``; the respective value is taken
951+
from :rc:`figure.figsize`.
952+
950953
dpi : float, default: :rc:`figure.dpi`
951954
The resolution of the figure in dots-per-inch.
952955

lib/matplotlib/tests/test_figure.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,24 @@ def test_figsize(figsize, figsize_inches):
18831883
assert tuple(fig.get_size_inches()) == figsize_inches
18841884

18851885

1886+
def test_figsize_partial_none():
1887+
default_w, default_h = mpl.rcParams["figure.figsize"]
1888+
1889+
fig = plt.figure(figsize=(None, 4))
1890+
w, h = fig.get_size_inches()
1891+
assert (w, h) == (default_w, 4)
1892+
1893+
fig = plt.figure(figsize=(6, None))
1894+
w, h = fig.get_size_inches()
1895+
assert (w, h) == (6, default_h)
1896+
1897+
1898+
def test_figsize_both_none():
1899+
with pytest.raises(ValueError,
1900+
match=r"figsize=\(None, None\) is invalid"):
1901+
plt.figure(figsize=(None, None))
1902+
1903+
18861904
def test_figsize_invalid_unit():
18871905
with pytest.raises(ValueError, match="Invalid unit 'um'"):
18881906
plt.figure(figsize=(6, 4, "um"))

0 commit comments

Comments
 (0)