From 2798e48df84d8545494c4d5ea6717ee4e5c9b307 Mon Sep 17 00:00:00 2001 From: Garvey Zhou Date: Sun, 11 Dec 2022 17:40:16 -0500 Subject: [PATCH 1/4] added getters and setters subplotparams for figure --- lib/matplotlib/figure.py | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 6c18ba1a643e..9d0585ab373f 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1171,6 +1171,61 @@ def text(self, x, y, s, fontdict=None, **kwargs): self.stale = True return text + def set_subplotparams(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_subplotparams + """ + 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_subplotparams;" + " this key was ignored.") + else: + raise TypeError( + "subplotparams must be a dictionary of keyword-argument pairs or" + " an instance of SubplotParams()") + if kwargs == {}: + self.set_subplotparams(self.get_subplotparams()) + self.subplots_adjust(**kwargs) + + def get_subplotparams(self): + """ + Return the `.SubplotParams` object associated with the Figure. + Returns + ------- + `.SubplotParams` + See Also + -------- + matplotlib.figure.Figure.subplots_adjust + matplotlib.figure.Figure.get_subplotparams + """ + return self.subplotpars + @_docstring.dedent_interpd def colorbar( self, mappable, cax=None, ax=None, use_gridspec=True, **kwargs): @@ -2277,6 +2332,10 @@ def draw(self, renderer): @_docstring.interpd +@_api.define_aliases({ + "size_inches": ["figsize"], + "layout_engine": ["layout"] +}) class Figure(FigureBase): """ The top level container for all the plot elements. From c06078f497389eea4630b6bc9ab2a511c549306a Mon Sep 17 00:00:00 2001 From: Garvey Zhou Date: Sun, 11 Dec 2022 17:40:44 -0500 Subject: [PATCH 2/4] added tests for getters and setters for figure --- lib/matplotlib/tests/test_figure.py | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index 86d7fb8591af..58eeda10d78b 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -1445,3 +1445,41 @@ def test_gridspec_no_mutate_input(): plt.subplots(1, 2, width_ratios=[1, 2], gridspec_kw=gs) assert gs == gs_orig plt.subplot_mosaic('AB', width_ratios=[1, 2], gridspec_kw=gs) + +def test_get_subplot_params(): + fig = plt.figure() + subplotparams_keys = ["left", "bottom", "right", "top", "wspace", "hspace"] + subplotparams = fig.get_subplotparams() + test_dict = {} + for key in subplotparams_keys: + attr = getattr(subplotparams, key) + assert attr == mpl.rcParams[f"figure.subplot.{key}"] + test_dict[key] = attr * 2 + + fig.set_subplotparams(test_dict) + for key, value in test_dict.items(): + assert getattr(fig.get_subplotparams(), key) == value + + test_dict['foo'] = 'bar' + with pytest.warns(UserWarning, + match="'foo' is not a valid key for set_subplotparams;" + " this key was ignored"): + fig.set_subplotparams(test_dict) + + with pytest.raises(TypeError, + match="subplotparams must be a dictionary of " + "keyword-argument pairs or " + "an instance of SubplotParams()"): + fig.set_subplotparams(['foo']) + + assert fig.subplotpars == fig.get_subplotparams() + + +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}") \ No newline at end of file From 119f4e7ae94725793c19494bbc5237f55141cd28 Mon Sep 17 00:00:00 2001 From: Garvey Zhou Date: Sun, 11 Dec 2022 18:48:52 -0500 Subject: [PATCH 3/4] fixed flake8 style --- lib/matplotlib/figure.py | 4 ++-- lib/matplotlib/tests/test_figure.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 9d0585ab373f..3099541b41a5 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1207,8 +1207,8 @@ def set_subplotparams(self, subplotparams={}): " this key was ignored.") else: raise TypeError( - "subplotparams must be a dictionary of keyword-argument pairs or" - " an instance of SubplotParams()") + "subplotparams must be a dictionary of keyword-argument pairs" + " or an instance of SubplotParams()") if kwargs == {}: self.set_subplotparams(self.get_subplotparams()) self.subplots_adjust(**kwargs) diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index 58eeda10d78b..eb70dfffeb61 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -1446,6 +1446,7 @@ def test_gridspec_no_mutate_input(): assert gs == gs_orig plt.subplot_mosaic('AB', width_ratios=[1, 2], gridspec_kw=gs) + def test_get_subplot_params(): fig = plt.figure() subplotparams_keys = ["left", "bottom", "right", "top", "wspace", "hspace"] @@ -1459,7 +1460,7 @@ def test_get_subplot_params(): fig.set_subplotparams(test_dict) for key, value in test_dict.items(): assert getattr(fig.get_subplotparams(), key) == value - + test_dict['foo'] = 'bar' with pytest.warns(UserWarning, match="'foo' is not a valid key for set_subplotparams;" @@ -1482,4 +1483,4 @@ def test_fig_get_set(): 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}") \ No newline at end of file + setfunc = getattr(fig, f"set_{var}") From 2714ef9ba03b8b75917ad986b7d236ef1debaaa7 Mon Sep 17 00:00:00 2001 From: Garvey Zhou Date: Sun, 11 Dec 2022 18:55:22 -0500 Subject: [PATCH 4/4] fix lint for figure.py --- lib/matplotlib/figure.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 3099541b41a5..db91b6978675 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1178,6 +1178,7 @@ def set_subplotparams(self, subplotparams={}): 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 \ @@ -1186,6 +1187,7 @@ def set_subplotparams(self, subplotparams={}): 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 @@ -1216,9 +1218,11 @@ def set_subplotparams(self, subplotparams={}): def get_subplotparams(self): """ Return the `.SubplotParams` object associated with the Figure. + Returns ------- `.SubplotParams` + See Also -------- matplotlib.figure.Figure.subplots_adjust