diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 04f0e73d2671..b9a789d57c93 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -183,6 +183,7 @@ class FigureBase(Artist): Base class for `.figure.Figure` and `.figure.SubFigure` containing the methods that add artists to the figure or subfigure, create Axes, etc. """ + def __init__(self, **kwargs): super().__init__() # remove the non-figure artist _axes property @@ -1051,9 +1052,9 @@ def legend(self, *args, **kwargs): """ handles, labels, extra_args, kwargs = mlegend._parse_legend_args( - self.axes, - *args, - **kwargs) + self.axes, + *args, + **kwargs) # check for third arg if len(extra_args): # _api.warn_deprecated( @@ -1191,6 +1192,11 @@ def subplots_adjust(self, left=None, bottom=None, right=None, top=None, hspace : float, optional The height of the padding between subplots, as a fraction of the average Axes height. + + See Also + -------- + matplotlib.figure.Figure.set_subplotpars + matplotlib.figure.Figure.get_subplotpars """ if self.get_constrained_layout(): self.set_constrained_layout(False) @@ -1204,6 +1210,65 @@ def subplots_adjust(self, left=None, bottom=None, right=None, top=None, ax._set_position(ax.get_subplotspec().get_position(self)) self.stale = True + def set_subplotpars(self, subplotparams={}): + """ + Set the subplot layout parameters. + Accepts either a `.SubplotParams` object, from which the relevant + parameters are copied, or a dictionary of subplot layout parameters. + If a dictionary is provided, this function is a convenience wrapper for + `matplotlib.figure.Figure.subplots_adjust` + + Parameters + ---------- + subplotparams : `~matplotlib.figure.SubplotParams` or dict with keys \ +"left", "bottom", "right", 'top", "wspace", "hspace"] , optional + SubplotParams object to copy new subplot parameters from, or a dict + of SubplotParams constructor arguments. + By default, an empty dictionary is passed, which maintains the + current state of the figure's `.SubplotParams` + + See Also + -------- + matplotlib.figure.Figure.subplots_adjust + matplotlib.figure.Figure.get_subplotpars + """ + subplotparams_args = ["left", "bottom", "right", + "top", "wspace", "hspace"] + kwargs = {} + if isinstance(subplotparams, SubplotParams): + for key in subplotparams_args: + kwargs[key] = getattr(subplotparams, key) + elif isinstance(subplotparams, dict): + for key in subplotparams.keys(): + if key in subplotparams_args: + kwargs[key] = subplotparams[key] + else: + _api.warn_external( + f"'{key}' is not a valid key for set_subplotpars;" + " this key was ignored.") + else: + raise TypeError( + "subplotpars must be a dictionary of keyword-argument pairs or" + " an instance of SubplotParams()") + if kwargs == {}: + self.set_subplotpars(self.get_subplotpars()) + self.subplots_adjust(**kwargs) + + def get_subplotpars(self): + """ + Return the `.SubplotParams` object associated with the Figure. + + Returns + ------- + `.SubplotParams` + + See Also + -------- + matplotlib.figure.Figure.subplots_adjust + matplotlib.figure.Figure.get_subplotpars + """ + return self.subplotpars + def align_xlabels(self, axs=None): """ Align the xlabels of subplots in the same subplot column if label @@ -2115,6 +2180,9 @@ def draw(self, renderer): @docstring.interpd +@cbook._define_aliases({ + "size_inches": ["figsize"] +}) class Figure(FigureBase): """ The top level container for all the plot elements. @@ -2231,24 +2299,6 @@ def __init__(self, """ super().__init__(**kwargs) - if layout is not None: - if tight_layout is not None: - _api.warn_external( - "The Figure parameters 'layout' and 'tight_layout' " - "cannot be used together. Please use 'layout' only.") - if constrained_layout is not None: - _api.warn_external( - "The Figure parameters 'layout' and 'constrained_layout' " - "cannot be used together. Please use 'layout' only.") - if layout == 'constrained': - tight_layout = False - constrained_layout = True - elif layout == 'tight': - tight_layout = True - constrained_layout = False - else: - _api.check_in_list(['constrained', 'tight'], layout=layout) - self.callbacks = cbook.CallbackRegistry() # Callbacks traditionally associated with the canvas (and exposed with # a proxy property), but that actually need to be on the figure for @@ -2299,15 +2349,11 @@ def __init__(self, self.subplotpars = subplotpars # constrained_layout: - self._constrained = False - - self.set_tight_layout(tight_layout) self._axstack = _AxesStack() # track all figure axes and current axes self.clf() self._cachedRenderer = None - - self.set_constrained_layout(constrained_layout) + self.set_layout(layout, tight_layout, constrained_layout) # list of child gridspecs for this figure self._gridspecs = [] @@ -2399,11 +2445,172 @@ def _set_dpi(self, dpi, forward=True): dpi = property(_get_dpi, _set_dpi, doc="The resolution in dots per inch.") + @property + def layout(self): + """ + Return the current figure layout solver. + """ + if hasattr(self, '_constrained'): + if self.get_constrained_layout(): + layout = 'constrained' + elif self.get_tight_layout(): + layout = 'tight' + else: + layout = None + else: + layout = None + return layout + + def get_layout(self): + """ + Return the current figure layout solver. + """ + return self.layout + + def set_layout(self, layout=None, tight_layout=None, + constrained_layout=None): + """ + Set the figure layout specification. (Optionally) sets how + `.tight_layout` or `.set_constrained_layout` is used when a dict is + provided to *tight_layout* or *constrained_layout*. + + + - If *layout* is not *None*, the layout solver is determined + exclusively by *layout*, regardless of *tight_layout* or + *constrained_layout*, but optional padding parameters stored in + *tight_layout* or *constrained_layout* are used with the respective + layout. + For instance: + + - if *layout* is *'tight'*, *tight_layout* is *False*, and + *constrained_layout* is *True*, `.tight_layout` with default paddings + is used to format the figure. + + - If *layout* is *'constrained'*, *tight_layout* is *{'pad':1}*, and + *constrained_layout* is *{'w_pad':1}*, then + `.set_constrained_layout` is called with padding parameters + *{'w_pad':1}*. + + - If *layout* is None, *tight_layout* and *constrained_layout* are + mutually exclusive. That is, only one can be *True* or a dict, as + resolving the case where both are not *False* and *layout* is *None* + is ambiguous. + + Parameters + ---------- + layout : {'constrained', 'tight', None}, optional + The layout mechanism for positioning of plot elements. + Supported values: + + - 'constrained': The constrained layout solver usually gives the + best layout results and is thus recommended. However, it is + computationally expensive and can be slow for complex figures + with many elements. + + See :doc:`/tutorials/intermediate/constrainedlayout_guide` + for examples. + + - 'tight': Use the tight layout mechanism. This is a relatively + simple algorithm, that adjusts the subplot parameters so that + decorations like tick labels, axis labels and titles have enough + space. See `.Figure.set_tight_layout` for further details. + + If not given, fall back to using the parameters *tight_layout* and + *constrained_layout*, including their config defaults + :rc:`figure.autolayout` and :rc:`figure.constrained_layout.use`. + tight_layout : bool or dict with keys "pad", "w_pad", "h_pad", \ +"rect", or None + If a bool, sets whether to call `.tight_layout` upon drawing. + If ``None``, use :rc:`figure.autolayout` instead. + If a dict, pass it as kwargs to `.tight_layout`, overriding the + default paddings. + constrained_layout : bool or dict with keys "w_pad", "h_pad", \ +"wspace", "hspace" or None + If a bool, sets whether to use ``constrained_layout`` upon drawing. + If ``None``, use :rc:`figure.autolayout` instead. + If a dict, pass it as kwargs to `.set_constrained_layout`, + overriding the default paddings. + """ + if ( + layout is None and + tight_layout is None and + constrained_layout is None + ): + layout = self.get_layout() + + if layout is not None: + # these will store the state of any warnings we need to pop + layout_clash = False + bool_conflict = False + type_conflict = False + + if layout == 'constrained': + layoutstr = 'constrained_layout' + falselayoutstr = 'tight_layout' + layout_clash = tight_layout not in [False, None] + tight_layout = False + bool_conflict = ( + isinstance(constrained_layout, bool) and + not constrained_layout + ) + type_conflict = not isinstance(constrained_layout, + (dict, bool, type(None))) + if ( + bool_conflict or + type_conflict or + constrained_layout is None + ): + constrained_layout = True + + elif layout == 'tight': + layoutstr = 'tight_layout' + falselayoutstr = 'constrained_layout' + layout_clash = constrained_layout not in [False, None] + constrained_layout = False + bool_conflict = ( + isinstance(tight_layout, bool) and + not tight_layout + ) + type_conflict = not isinstance(tight_layout, + (dict, bool, type(None))) + if bool_conflict or type_conflict or tight_layout is None: + tight_layout = True + else: + _api.check_in_list(['constrained', 'tight'], layout=layout) + + if layout_clash: + _api.warn_external(f"Figure parameters " + f"'layout'=='{layout}' and " + f"'{falselayoutstr}'!=False cannot " + f"be used together. " + f"Please use 'layout' only.") + if bool_conflict: + _api.warn_external(f"Figure parameters " + f"'layout'=='{layout}' and " + f"'{layoutstr}'==False cannot be " + f"used together. " + f"Please use 'layout' only.") + if type_conflict: + _api.warn_external(f"Figure parameters " + f"'layout'=='{layout}' and " + f"'{layoutstr}' cannot be " + f"used together if '{layoutstr}' is " + f"not True or a dictionary of " + f"{layoutstr} arguments. " + f"Please use 'layout' only.") + else: + if all([tight_layout, constrained_layout]): + raise ValueError("Cannot set 'tight_layout' and " + "'constrained_layout' simultaneously.") + self._constrained = False + self.set_tight_layout(tight_layout) + self.set_constrained_layout(constrained_layout) + def get_tight_layout(self): """Return whether `.tight_layout` is called when drawing.""" return self._tight - def set_tight_layout(self, tight): + def set_tight_layout(self, tight=None): """ Set whether and how `.tight_layout` is called when drawing. @@ -2429,7 +2636,7 @@ def get_constrained_layout(self): """ return self._constrained - def set_constrained_layout(self, constrained): + def set_constrained_layout(self, constrained=None): """ Set whether ``constrained_layout`` is used upon drawing. If None, :rc:`figure.constrained_layout.use` value will be used. diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index cb8f63893aea..7dbd017cb668 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -10,12 +10,13 @@ import pytest from PIL import Image + import matplotlib as mpl from matplotlib import cbook, rcParams from matplotlib._api.deprecation import MatplotlibDeprecationWarning from matplotlib.testing.decorators import image_comparison, check_figures_equal from matplotlib.axes import Axes -from matplotlib.figure import Figure +from matplotlib.figure import Figure, SubplotParams from matplotlib.ticker import AutoMinorLocator, FixedFormatter, ScalarFormatter import matplotlib.pyplot as plt import matplotlib.dates as mdates @@ -350,6 +351,10 @@ def test_set_fig_size(): assert fig.get_figwidth() == 1 assert fig.get_figheight() == 3 + fig.set_figsize(2, 4) + assert fig.get_figsize()[0] == 2 + assert fig.get_figsize()[1] == 4 + def test_axes_remove(): fig, axs = plt.subplots(2, 2) @@ -539,30 +544,317 @@ def test_valid_layouts(): assert not fig.get_tight_layout() assert fig.get_constrained_layout() + fig = Figure(tight_layout={'pad': 1}) + assert fig.get_tight_layout() + assert not fig.get_constrained_layout() + + fig = Figure(tight_layout=True) + assert fig.get_tight_layout() + assert not fig.get_constrained_layout() + + fig = Figure(tight_layout=True, constrained_layout=False) + assert fig.get_tight_layout() + assert not fig.get_constrained_layout() + + fig = Figure(constrained_layout={'w_pad': 1}) + assert not fig.get_tight_layout() + assert fig.get_constrained_layout() + + fig = Figure(constrained_layout=True) + assert not fig.get_tight_layout() + assert fig.get_constrained_layout() + + fig = Figure(constrained_layout=True, tight_layout=False) + assert not fig.get_tight_layout() + assert fig.get_constrained_layout() + + fig = Figure(layout='tight', tight_layout={'pad': 1}) + assert fig.get_tight_layout() + assert not fig.get_constrained_layout() + + fig = Figure(layout='constrained', constrained_layout={'w_pad': 1}) + assert not fig.get_tight_layout() + assert fig.get_constrained_layout() + + fig = Figure(layout='tight', tight_layout={'pad': 1}, + constrained_layout=False) + assert fig.get_tight_layout() + assert not fig.get_constrained_layout() + + fig = Figure(layout='constrained', constrained_layout={'w_pad': 1}, + tight_layout=False) + assert not fig.get_tight_layout() + assert fig.get_constrained_layout() + fig = Figure(layout=None, constrained_layout=False, + tight_layout=False) + assert not fig.get_tight_layout() + assert not fig.get_constrained_layout() + def test_invalid_layouts(): + + def assert_is_tight(fig): + assert fig.get_tight_layout() + assert not fig.get_constrained_layout() + assert fig.layout == 'tight' + + def assert_is_constrained(fig): + assert not fig.get_tight_layout() + assert fig.get_constrained_layout() + assert fig.layout == 'constrained' + + def assert_neither(fig): + assert not fig.get_tight_layout() + assert not fig.get_constrained_layout() + assert fig.layout is None fig, ax = plt.subplots(constrained_layout=True) with pytest.warns(UserWarning): # this should warn, fig.subplots_adjust(top=0.8) - assert not(fig.get_constrained_layout()) - + assert_neither(fig) # Using layout + (tight|constrained)_layout warns, but the former takes # precedence. - with pytest.warns(UserWarning, match="Figure parameters 'layout' and " - "'tight_layout' cannot"): + + # check the set_layout function on figure construction: + with pytest.warns(UserWarning, match="Figure parameters 'layout'=='tight'" + " and 'tight_layout'==False cannot"): fig = Figure(layout='tight', tight_layout=False) - assert fig.get_tight_layout() - assert not fig.get_constrained_layout() - with pytest.warns(UserWarning, match="Figure parameters 'layout' and " - "'constrained_layout' cannot"): + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'constrained_layout'==False cannot"): fig = Figure(layout='constrained', constrained_layout=False) - assert not fig.get_tight_layout() - assert fig.get_constrained_layout() + assert_is_constrained(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='tight' and " + "'constrained_layout'!=False cannot"): + fig = Figure(layout='tight', constrained_layout=True) + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'tight_layout'!=False cannot"): + fig = Figure(layout='constrained', tight_layout=True) + assert_is_constrained(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='tight' and " + "'constrained_layout'!=False cannot"): + fig = Figure(layout='tight', tight_layout=True, + constrained_layout=True) + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='tight' and " + "'constrained_layout'!=False cannot"): + fig = Figure(layout='tight', tight_layout={'pad': 1}, + constrained_layout=True) + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='tight' and " + "'constrained_layout'!=False cannot"): + fig = Figure(layout='tight', tight_layout={'pad': 1}, + constrained_layout={'w_pad': 1}) + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='tight' and " + "'constrained_layout'!=False cannot"): + fig = Figure(layout='tight', tight_layout=True, + constrained_layout={'w_pad': 1}) + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'tight_layout'!=False cannot"): + fig = Figure(layout='constrained', constrained_layout=True, + tight_layout=True) + assert_is_constrained(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'tight_layout'!=False cannot"): + fig = Figure(layout='constrained', constrained_layout={'w_pad': 1}, + tight_layout=True) + assert_is_constrained(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'tight_layout'!=False cannot"): + fig = Figure(layout='constrained', constrained_layout={'w_pad': 1}, + tight_layout={'pad': 1}) + assert_is_constrained(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'tight_layout'!=False cannot"): + fig = Figure(layout='constrained', constrained_layout=True, + tight_layout={'pad': 1}) + assert_is_constrained(fig) + + with pytest.warns(Warning) as warninfo: + fig = Figure(layout='tight', + tight_layout=False, + constrained_layout=True) + warns = {(warn.category, warn.message.args[0]) for warn in warninfo} + expected = { + (UserWarning, "Figure parameters 'layout'=='tight' " + "and 'tight_layout'==False cannot be used together. " + "Please use 'layout' only."), + (UserWarning, "Figure parameters 'layout'=='tight' " + "and 'constrained_layout'!=False cannot be used together. " + "Please use 'layout' only.")} + assert_is_tight(fig) + assert warns == expected + with pytest.warns(Warning) as warninfo: + fig = Figure(layout='constrained', + tight_layout=True, + constrained_layout=False) + warns = {(warn.category, warn.message.args[0]) for warn in warninfo} + expected = { + (UserWarning, "Figure parameters 'layout'=='constrained' " + "and 'tight_layout'!=False cannot be used together. " + "Please use 'layout' only."), + (UserWarning, "Figure parameters 'layout'=='constrained' " + "and 'constrained_layout'==False cannot be used together. " + "Please use 'layout' only.")} + assert_is_constrained(fig) + assert warns == expected with pytest.raises(ValueError, match="'foobar' is not a valid value for layout"): Figure(layout='foobar') + # now check the set_layout function after figure_construction + + fig = Figure(layout='tight') + with pytest.warns(UserWarning, match="Figure parameters 'layout'=='tight' " + "and 'tight_layout'==False cannot"): + fig.set_layout(layout='tight', tight_layout=False) + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'constrained_layout'==False cannot"): + fig.set_layout(layout='constrained', constrained_layout=False) + assert_is_constrained(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='tight' and " + "'constrained_layout'!=False cannot"): + fig.set_layout(layout='tight', constrained_layout=True) + assert_is_tight(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'tight_layout'!=False cannot"): + fig.set_layout(layout='constrained', tight_layout=True) + assert_is_constrained(fig) + + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='tight' and " + "'constrained_layout'!=False cannot"): + fig.set_layout(layout='tight', constrained_layout={'pad': 1}) + assert_is_tight(fig) + with pytest.warns(UserWarning, match="Figure parameters " + "'layout'=='constrained' and " + "'tight_layout'!=False cannot"): + fig.set_layout(layout='constrained', tight_layout={'pad': 1}) + assert_is_constrained(fig) + + with pytest.warns(Warning) as warninfo: + fig.set_layout(layout='tight', + tight_layout=False, + constrained_layout=True) + warns = {(warn.category, warn.message.args[0]) for warn in warninfo} + expected = { + (UserWarning, "Figure parameters 'layout'=='tight' " + "and 'tight_layout'==False cannot be used together. " + "Please use 'layout' only."), + (UserWarning, "Figure parameters 'layout'=='tight' " + "and 'constrained_layout'!=False cannot be used together. " + "Please use 'layout' only.")} + assert_is_tight(fig) + assert warns == expected + with pytest.warns(Warning) as warninfo: + fig.set_layout(layout='constrained', + tight_layout=True, + constrained_layout=False) + warns = {(warn.category, warn.message.args[0]) for warn in warninfo} + expected = { + (UserWarning, "Figure parameters 'layout'=='constrained' " + "and 'tight_layout'!=False cannot be used together. " + "Please use 'layout' only."), + (UserWarning, "Figure parameters 'layout'=='constrained' " + "and 'constrained_layout'==False cannot be used together. " + "Please use 'layout' only.")} + assert_is_constrained(fig) + assert warns == expected + + with pytest.raises(ValueError, + match="Cannot set 'tight_layout' and " + "'constrained_layout' simultaneously."): + fig = Figure(tight_layout={'w': 1}, constrained_layout={'w_pad': 1}) + with pytest.raises(ValueError, + match="Cannot set 'tight_layout' and " + "'constrained_layout' simultaneously."): + fig = Figure(tight_layout=True, constrained_layout={'w_pad': 1}) + with pytest.raises(ValueError, + match="Cannot set 'tight_layout' and " + "'constrained_layout' simultaneously."): + fig = Figure(tight_layout=True, constrained_layout=True) + + +def test_set_subplotpars(): + subplotparams_keys = ["left", "bottom", "right", "top", "wspace", "hspace"] + fig = plt.figure() + subplotparams = fig.get_subplotpars() + test_dict = {} + default_dict = {} + for key in subplotparams_keys: + attr = getattr(subplotparams, key) + assert attr == mpl.rcParams[f"figure.subplot.{key}"] + default_dict[key] = attr + test_dict[key] = attr * 2 + + subplotparams.update(left=test_dict['left']) + assert fig.get_subplotpars().left == test_dict['left'] + + fig.subplots_adjust(**default_dict) + assert fig.get_subplotpars().left == default_dict['left'] + + fig.set_subplotpars(test_dict) + for key, value in test_dict.items(): + assert getattr(fig.get_subplotpars(), key) == value + + test_subplotparams = SubplotParams() + fig.set_subplotpars(test_subplotparams) + for key, value in default_dict.items(): + assert getattr(fig.get_subplotpars(), key) == value + + fig.set_subplotpars(test_dict) + for key, value in test_dict.items(): + assert getattr(fig.get_subplotpars(), key) == value + + test_dict['foo'] = 'bar' + with pytest.warns(UserWarning, + match="'foo' is not a valid key for set_subplotpars;" + " this key was ignored"): + fig.set_subplotpars(test_dict) + + with pytest.raises(TypeError, + match="subplotpars must be a dictionary of " + "keyword-argument pairs or " + "an instance of SubplotParams()"): + fig.set_subplotpars(['foo']) + + fig.set_subplotpars({}) + with pytest.raises(AttributeError): # test_dict['foo'] = 'bar' + # but fig.get_subplotpars().foo should be invalid + for key, value in test_dict.items(): + assert getattr(fig.get_subplotpars(), key) == value @check_figures_equal(extensions=["png", "pdf"]) @@ -995,7 +1287,7 @@ def test_subfigure_tightbbox(): sub = fig.subfigures(1, 2) np.testing.assert_allclose( - fig.get_tightbbox(fig.canvas.get_renderer()).width, 0.1) + fig.get_tightbbox(fig.canvas.get_renderer()).width, 0.1) @image_comparison(['test_subfigure_ss.png'], style='mpl20', @@ -1078,11 +1370,11 @@ def test_subfigure_spanning(): w = 640 h = 480 - np.testing.assert_allclose(sub_figs[0].bbox.min, [0., h * 2/3]) + np.testing.assert_allclose(sub_figs[0].bbox.min, [0., h * 2 / 3]) np.testing.assert_allclose(sub_figs[0].bbox.max, [w / 3, h]) np.testing.assert_allclose(sub_figs[1].bbox.min, [w / 3, h / 3]) - np.testing.assert_allclose(sub_figs[1].bbox.max, [w * 2/3, h]) + np.testing.assert_allclose(sub_figs[1].bbox.max, [w * 2 / 3, h]) np.testing.assert_allclose(sub_figs[2].bbox.min, [w / 3, 0]) np.testing.assert_allclose(sub_figs[2].bbox.max, [w, h / 3]) @@ -1123,7 +1415,7 @@ def test_subfigure_ticks(): @image_comparison(['test_subfigure_scatter_size.png'], style='mpl20', - remove_text=True) + remove_text=True) def test_subfigure_scatter_size(): # markers in the left- and right-most subplots should be the same fig = plt.figure() @@ -1226,3 +1518,13 @@ def test_kwargs_pass(): assert fig.get_label() == 'whole Figure' assert sub_fig.get_label() == 'sub figure' + + +def test_fig_get_set(): + varnames = filter(lambda var: var not in ['self', 'kwargs', 'args'], + Figure.__init__.__code__.co_varnames) + fig = plt.figure() + for var in varnames: + # if getattr fails then the getter and setter does not exist + getfunc = getattr(fig, f"get_{var}") + setfunc = getattr(fig, f"set_{var}") pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy