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

Skip to content

Commit 33e51a5

Browse files
authored
Merge pull request #20170 from anntzer/spv
SubplotParams.validate-associated fixes.
2 parents 19aac39 + bfcb305 commit 33e51a5

File tree

6 files changed

+45
-28
lines changed

6 files changed

+45
-28
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
``SubplotParams.validate``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
... is deprecated. Use `.SubplotParams.update` to change `.SubplotParams`
4+
while always keeping it in a valid state.

lib/matplotlib/_api/deprecation.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,18 +282,20 @@ class Foo:
282282
attr = _deprecate_privatize_attribute(*args, **kwargs)
283283
284284
where *all* parameters are forwarded to `deprecated`. This form makes
285-
``attr`` a property which forwards access to ``self._attr`` (same name but
286-
with a leading underscore), with a deprecation warning. Note that the
287-
attribute name is derived from *the name this helper is assigned to*. This
288-
helper also works for deprecating methods.
285+
``attr`` a property which forwards read and write access to ``self._attr``
286+
(same name but with a leading underscore), with a deprecation warning.
287+
Note that the attribute name is derived from *the name this helper is
288+
assigned to*. This helper also works for deprecating methods.
289289
"""
290290

291291
def __init__(self, *args, **kwargs):
292292
self.deprecator = deprecated(*args, **kwargs)
293293

294294
def __set_name__(self, owner, name):
295295
setattr(owner, name, self.deprecator(
296-
property(lambda self: getattr(self, f"_{name}")), name=name))
296+
property(lambda self: getattr(self, f"_{name}"),
297+
lambda self, value: setattr(self, f"_{name}", value)),
298+
name=name))
297299

298300

299301
def rename_parameter(since, old, new, func=None):

lib/matplotlib/backends/backend_qt5.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -777,12 +777,6 @@ def __init__(self, targetfig, parent):
777777

778778
self._figure = targetfig
779779

780-
for lower, higher in [("bottom", "top"), ("left", "right")]:
781-
self._widgets[lower].valueChanged.connect(
782-
lambda val: self._widgets[higher].setMinimum(val + .001))
783-
self._widgets[higher].valueChanged.connect(
784-
lambda val: self._widgets[lower].setMaximum(val - .001))
785-
786780
self._attrs = ["top", "bottom", "left", "right", "hspace", "wspace"]
787781
self._defaults = {attr: vars(self._figure.subplotpars)[attr]
788782
for attr in self._attrs}
@@ -821,7 +815,12 @@ def _export_values(self):
821815
dialog.exec_()
822816

823817
def _on_value_changed(self):
824-
self._figure.subplots_adjust(**{attr: self._widgets[attr].value()
818+
widgets = self._widgets
819+
# Set all mins and maxes, so that this can also be used in _reset().
820+
for lower, higher in [("bottom", "top"), ("left", "right")]:
821+
widgets[higher].setMinimum(widgets[lower].value() + .001)
822+
widgets[lower].setMaximum(widgets[higher].value() - .001)
823+
self._figure.subplots_adjust(**{attr: widgets[attr].value()
825824
for attr in self._attrs})
826825
self._figure.canvas.draw_idle()
827826

@@ -836,7 +835,12 @@ def _tight_layout(self):
836835

837836
def _reset(self):
838837
for attr, value in self._defaults.items():
839-
self._widgets[attr].setValue(value)
838+
widget = self._widgets[attr]
839+
widget.setRange(0, 1)
840+
widget.blockSignals(True)
841+
widget.setValue(value)
842+
widget.blockSignals(False)
843+
self._on_value_changed()
840844

841845

842846
class ToolbarQt(ToolContainerBase, QtWidgets.QToolBar):

lib/matplotlib/figure.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class SubplotParams:
120120
"""
121121
A class to hold the parameters for a subplot.
122122
"""
123+
123124
def __init__(self, left=None, bottom=None, right=None, top=None,
124125
wspace=None, hspace=None):
125126
"""
@@ -146,17 +147,20 @@ def __init__(self, left=None, bottom=None, right=None, top=None,
146147
The height of the padding between subplots,
147148
as a fraction of the average Axes height.
148149
"""
149-
self.validate = True
150+
self._validate = True
150151
for key in ["left", "bottom", "right", "top", "wspace", "hspace"]:
151152
setattr(self, key, mpl.rcParams[f"figure.subplot.{key}"])
152153
self.update(left, bottom, right, top, wspace, hspace)
153154

155+
# Also remove _validate after deprecation elapses.
156+
validate = _api.deprecate_privatize_attribute("3.5")
157+
154158
def update(self, left=None, bottom=None, right=None, top=None,
155159
wspace=None, hspace=None):
156160
"""
157161
Update the dimensions of the passed parameters. *None* means unchanged.
158162
"""
159-
if self.validate:
163+
if self._validate:
160164
if ((left if left is not None else self.left)
161165
>= (right if right is not None else self.right)):
162166
raise ValueError('left cannot be >= right')

lib/matplotlib/tests/test_api.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,19 @@ def f(cls):
3737
def test_deprecate_privatize_attribute():
3838
class C:
3939
def __init__(self): self._attr = 1
40-
def _meth(self, arg): pass
40+
def _meth(self, arg): return arg
4141
attr = _api.deprecate_privatize_attribute("0.0")
4242
meth = _api.deprecate_privatize_attribute("0.0")
4343

44+
c = C()
4445
with pytest.warns(_api.MatplotlibDeprecationWarning):
45-
C().attr
46+
assert c.attr == 1
4647
with pytest.warns(_api.MatplotlibDeprecationWarning):
47-
C().meth(42)
48+
c.attr = 2
49+
with pytest.warns(_api.MatplotlibDeprecationWarning):
50+
assert c.attr == 2
51+
with pytest.warns(_api.MatplotlibDeprecationWarning):
52+
assert c.meth(42) == 42
4853

4954

5055
def test_delete_parameter():

lib/matplotlib/widgets.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,11 +1402,7 @@ def __init__(self, targetfig, toolfig):
14021402

14031403
bax = toolfig.add_axes([0.8, 0.05, 0.15, 0.075])
14041404
self.buttonreset = Button(bax, 'Reset')
1405-
1406-
# During reset there can be a temporary invalid state depending on the
1407-
# order of the reset so we turn off validation for the resetting
1408-
with cbook._setattr_cm(toolfig.subplotpars, validate=False):
1409-
self.buttonreset.on_clicked(self._on_reset)
1405+
self.buttonreset.on_clicked(self._on_reset)
14101406

14111407
def _on_slider_changed(self, _):
14121408
self.targetfig.subplots_adjust(
@@ -1417,17 +1413,19 @@ def _on_slider_changed(self, _):
14171413

14181414
def _on_reset(self, event):
14191415
with ExitStack() as stack:
1420-
# Temporarily disable drawing on self and self's sliders.
1416+
# Temporarily disable drawing on self and self's sliders, and
1417+
# disconnect slider events (as the subplotparams can be temporarily
1418+
# invalid, depending on the order in which they are restored).
14211419
stack.enter_context(cbook._setattr_cm(self, drawon=False))
14221420
for slider in self._sliders:
1423-
stack.enter_context(cbook._setattr_cm(slider, drawon=False))
1421+
stack.enter_context(
1422+
cbook._setattr_cm(slider, drawon=False, eventson=False))
14241423
# Reset the slider to the initial position.
14251424
for slider in self._sliders:
14261425
slider.reset()
1427-
# Draw the canvas.
14281426
if self.drawon:
1429-
event.canvas.draw()
1430-
self.targetfig.canvas.draw()
1427+
event.canvas.draw() # Redraw the subplottool canvas.
1428+
self._on_slider_changed(None) # Apply changes to the target window.
14311429

14321430
axleft = _api.deprecated("3.3")(
14331431
property(lambda self: self.sliderleft.ax))

0 commit comments

Comments
 (0)