From 5586d43a434f6de5dc09d207c7f0b76d05fee681 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Fri, 20 Nov 2015 21:03:04 -0800 Subject: [PATCH 1/4] Turn autoscale into a contextmanager. See #5510. Also clarify a bit the implementation of autoscale, and fix an issue about the lack of effect of set_autoscalez_on for 3D axes, which was previously visible by running:: from pylab import * from mpl_toolkits import mplot3d gcf().add_subplot(111, projection="3d") plot([0, 1], [0, 1], [0, 1]) gca().set_autoscalex_on(False) gca().set_autoscalez_on(False) # has no effect plot([2, 3], [2, 3], [2, 3]) show() --- lib/matplotlib/axes/_base.py | 35 +++++++++++++++++++++--------- lib/mpl_toolkits/mplot3d/axes3d.py | 33 ++++++++++++++++------------ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index b0637aef6500..efadd2b13a1c 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -4,6 +4,7 @@ from matplotlib.externals import six from matplotlib.externals.six.moves import xrange +from contextlib import contextmanager import itertools import warnings import math @@ -2103,22 +2104,36 @@ def autoscale(self, enable=True, axis='both', tight=None): The *tight* setting is retained for future autoscaling until it is explicitly changed. + This returns a context-manager/decorator that allows temporarily + setting the autoscale status, i.e.:: - Returns None. + with axes.autoscale(enable): ... + + or:: + + @axes.autoscale(enable) + def func(): ... + + will keep the autoscale status to `enable` for the duration of the + block or function and then restore it to its original value. """ - if enable is None: - scalex = True - scaley = True - else: - scalex = False - scaley = False + orig_autoscale = self._autoscaleXon, self._autoscaleYon + if enable is not None: if axis in ['x', 'both']: self._autoscaleXon = bool(enable) - scalex = self._autoscaleXon if axis in ['y', 'both']: self._autoscaleYon = bool(enable) - scaley = self._autoscaleYon - self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley) + self.autoscale_view( + tight=tight, scalex=self._autoscaleXon, scaley=self._autoscaleYon) + + @contextmanager + def restore_autoscaling(): + try: + yield + finally: + self._autoscaleXon, self._autoscaleYon = orig_autoscale + + return restore_autoscaling() def autoscale_view(self, tight=None, scalex=True, scaley=True): """ diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 59ce4e6626f3..78e8cfcd4d45 100755 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -11,6 +11,7 @@ """ from __future__ import (absolute_import, division, print_function, unicode_literals) +from contextlib import contextmanager import math from matplotlib.externals import six @@ -342,7 +343,7 @@ def set_autoscalez_on(self, b) : .. versionadded :: 1.1.0 This function was added, but not tested. Please report any bugs. """ - self._autoscalez_on = b + self._autoscaleZon = b def set_zmargin(self, m) : """ @@ -438,25 +439,29 @@ def autoscale(self, enable=True, axis='both', tight=None) : .. versionadded :: 1.1.0 This function was added, but not tested. Please report any bugs. """ - if enable is None: - scalex = True - scaley = True - scalez = True - else: - scalex = False - scaley = False - scalez = False + orig_autoscale = ( + self._autoscaleXon, self._autoscaleYon, self._autoscaleZon) + if enable is not None: if axis in ['x', 'both']: self._autoscaleXon = bool(enable) - scalex = self._autoscaleXon if axis in ['y', 'both']: self._autoscaleYon = bool(enable) - scaley = self._autoscaleYon if axis in ['z', 'both']: self._autoscaleZon = bool(enable) - scalez = self._autoscaleZon - self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley, - scalez=scalez) + self.autoscale_view(tight=tight, + scalex=self._autoscaleXon, + scaley=self._autoscaleYon, + scalez=self._autoscaleZon) + + @contextmanager + def restore_autoscaling(): + try: + yield + finally: + self._autoscaleXon, self._autoscaleYon, self._autoscaleZon = ( + orig_autoscale) + + return restore_autoscaling() def auto_scale_xyz(self, X, Y, Z=None, had_data=None): x, y, z = list(map(np.asarray, (X, Y, Z))) From 4f30ccec5e3314da2ad7860c3e7503d72e13a4f5 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sun, 22 Nov 2015 18:02:44 -0800 Subject: [PATCH 2/4] Add basic test for switching autoscale status. --- lib/matplotlib/tests/test_axes.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 5a3e6ee70e13..35cc3836c35e 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4118,6 +4118,23 @@ def test_axisbg_warning(): ("The axisbg attribute was deprecated in version 2.0."))) +@cleanup +def test_autoscale(): + plt.plot([0, 1], [0, 1]) + assert_equal(plt.xlim(), (0, 1)) + plt.autoscale(False) + plt.plot([2, 3], [2, 3]) + assert_equal(plt.xlim(), (0, 1)) + plt.autoscale(True) + plt.plot([1, 2], [1, 2]) + assert_equal(plt.xlim(), (0, 3)) + with plt.autoscale(False): + plt.plot([3, 4], [3, 4]) + assert_equal(plt.xlim(), (0, 3)) + plt.plot([4, 5], [4, 5]) + assert_equal(plt.xlim(), (0, 5)) + + if __name__ == '__main__': import nose import sys From 90397f9c5903210e24531756b92c3ebd6cd54c19 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 23 Nov 2015 07:37:58 -0800 Subject: [PATCH 3/4] Documentation for the autoscale contextmanager. --- doc/api/api_changes.rst | 13 +++++++++++++ doc/users/whats_new.rst | 12 ++++++++++++ lib/matplotlib/axes/_base.py | 7 +------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index 119816a18c74..85d823b18d08 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -11,6 +11,19 @@ sources of the changes you are experiencing. For new features that were added to matplotlib, please see :ref:`whats-new`. +Changes in 2.1.0 +================ + +Code changes +------------ + +autoscale is now a context manager +`````````````````````````````````` + +Instead of returning None, ``plt.autoscale`` and ``Axes.autoscale`` +now return a context manager, which allows one to restore the previous +autoscaling status upon exiting the block. + Changes in 2.0.0 ================ diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index c1657092b6ce..7107cb88c920 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -23,6 +23,18 @@ revision, see the :ref:`github-stats`. .. contents:: Table of Contents :depth: 3 +.. _whats-new-2-1: + +new in matplotlib-2.1 +===================== + +autoscale is now a context manager +---------------------------------- + +Instead of returning None, ``plt.autoscale`` and ``Axes.autoscale`` +now return a context manager, which allows one to restore the previous +autoscaling status upon exiting the block. + .. _whats-new-1-5: new in matplotlib-1.5 diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index efadd2b13a1c..094b86a461c3 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2109,13 +2109,8 @@ def autoscale(self, enable=True, axis='both', tight=None): with axes.autoscale(enable): ... - or:: - - @axes.autoscale(enable) - def func(): ... - will keep the autoscale status to `enable` for the duration of the - block or function and then restore it to its original value. + block only. """ orig_autoscale = self._autoscaleXon, self._autoscaleYon if enable is not None: From 498166d309d9a46a1edd0d46d524753e702639fd Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 23 Nov 2015 23:26:49 -0800 Subject: [PATCH 4/4] WIP: Fix autoscale(None)? --- lib/matplotlib/tests/test_axes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 35cc3836c35e..8d391ba08ca0 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4125,8 +4125,7 @@ def test_autoscale(): plt.autoscale(False) plt.plot([2, 3], [2, 3]) assert_equal(plt.xlim(), (0, 1)) - plt.autoscale(True) - plt.plot([1, 2], [1, 2]) + plt.autoscale(None) assert_equal(plt.xlim(), (0, 3)) with plt.autoscale(False): plt.plot([3, 4], [3, 4]) 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