@@ -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 if not np .isfinite (figsize ).all () or (np .array (figsize ) < 0 ).any ():
26162623 raise ValueError ('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 return newsize
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+ if num_parts == 2 :
3744+ return figsize
3745+ elif num_parts == 3 :
3746+ x , y , unit = figsize
3747+ if unit == 'in' :
3748+ pass
3749+ elif unit == 'cm' :
3750+ x /= 2.54
3751+ y /= 2.54
3752+ elif unit == 'px' :
3753+ x /= dpi
3754+ y /= dpi
3755+ else :
3756+ raise ValueError (
3757+ f"Invalid unit { unit !r} in 'figsize'; "
3758+ "supported units are 'in', 'cm', 'px'"
3759+ )
3760+ return x , y
3761+ else :
3762+ raise ValueError (
3763+ "Invalid figsize format, expected (x, y) or (x, y, unit) but got "
3764+ f"{ figsize !r} "
3765+ )
0 commit comments