From eb489f65cdd19857d8d7d4eee4a10cce22e1f713 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Tue, 31 Jul 2018 16:30:31 +0100 Subject: [PATCH 01/12] Merge pull request #9993 from anntzer/qtcompat Rewrite and greatly simplify qt_compat.py. Conflicts: INSTALL.rst - kept changes away from App specific wording - kept min pyqt4 version bump doc/sphinxext/mock_gui_toolkits.py - only removed setting up the Qt mocks lib/matplotlib/backends/qt_compat.py - kept backported version, conflict was in block of constants at top (all of the contestants are still defined in the module) --- INSTALL.rst | 8 +- doc/api/backend_qt4agg_api.rst | 10 +- doc/api/backend_qt4cairo_api.rst | 10 +- doc/api/backend_qt5agg_api.rst | 10 +- doc/api/backend_qt5cairo_api.rst | 10 +- doc/sphinxext/mock_gui_toolkits.py | 104 --------- lib/matplotlib/backends/qt_compat.py | 336 +++++++++++---------------- 7 files changed, 167 insertions(+), 321 deletions(-) diff --git a/INSTALL.rst b/INSTALL.rst index 56ecd9a31e2e..99184145f05c 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -188,10 +188,10 @@ Optionally, you can also install a number of packages to enable better user interface toolkits. See :ref:`what-is-a-backend` for more details on the optional Matplotlib backends and the capabilities they provide. - * :term:`tk` (>= 8.3, != 8.6.0 or 8.6.1): for the TkAgg backend; - * `PyQt4 `_ (>= 4.4) or - `PySide `_: for the Qt4Agg backend; - * `PyQt5 `_: for the Qt5Agg backend; + * :term:`tk` (>= 8.3, != 8.6.0 or 8.6.1): for the Tk-based backends; + * `PyQt4 `_ (>= 4.6) or + `PySide `_: for the Qt4-based backend; + * `PyQt5 `_: for the Qt5-based backend; * :term:`pygtk` (>= 2.4): for the GTK and the GTKAgg backend; * :term:`wxpython` (>= 2.9 or later): for the WX or WXAgg backend; * `cairocffi `__ (>= diff --git a/doc/api/backend_qt4agg_api.rst b/doc/api/backend_qt4agg_api.rst index 8bf490aa8cb9..8b787512a44c 100644 --- a/doc/api/backend_qt4agg_api.rst +++ b/doc/api/backend_qt4agg_api.rst @@ -2,7 +2,9 @@ :mod:`matplotlib.backends.backend_qt4agg` ========================================= -.. automodule:: matplotlib.backends.backend_qt4agg - :members: - :undoc-members: - :show-inheritance: +**NOTE** Not included, to avoid adding a dependency to building the docs. + +.. .. automodule:: matplotlib.backends.backend_qt4agg +.. :members: +.. :undoc-members: +.. :show-inheritance: diff --git a/doc/api/backend_qt4cairo_api.rst b/doc/api/backend_qt4cairo_api.rst index 590465d7fbc0..1e6cb526de96 100644 --- a/doc/api/backend_qt4cairo_api.rst +++ b/doc/api/backend_qt4cairo_api.rst @@ -2,7 +2,9 @@ :mod:`matplotlib.backends.backend_qt4cairo` =========================================== -.. automodule:: matplotlib.backends.backend_qt4cairo - :members: - :undoc-members: - :show-inheritance: +**NOTE** Not included, to avoid adding a dependency to building the docs. + +.. .. automodule:: matplotlib.backends.backend_qt4cairo +.. :members: +.. :undoc-members: +.. :show-inheritance: diff --git a/doc/api/backend_qt5agg_api.rst b/doc/api/backend_qt5agg_api.rst index 8d1ad2aba0f0..f8400aefa1a2 100644 --- a/doc/api/backend_qt5agg_api.rst +++ b/doc/api/backend_qt5agg_api.rst @@ -2,7 +2,9 @@ :mod:`matplotlib.backends.backend_qt5agg` ========================================= -.. automodule:: matplotlib.backends.backend_qt5agg - :members: - :undoc-members: - :show-inheritance: +**NOTE** Not included, to avoid adding a dependency to building the docs. + +.. .. automodule:: matplotlib.backends.backend_qt5agg +.. :members: +.. :undoc-members: +.. :show-inheritance: diff --git a/doc/api/backend_qt5cairo_api.rst b/doc/api/backend_qt5cairo_api.rst index 73df7ac128a1..7ff3e1233b43 100644 --- a/doc/api/backend_qt5cairo_api.rst +++ b/doc/api/backend_qt5cairo_api.rst @@ -2,7 +2,9 @@ :mod:`matplotlib.backends.backend_qt5cairo` =========================================== -.. automodule:: matplotlib.backends.backend_qt5cairo - :members: - :undoc-members: - :show-inheritance: +**NOTE** Not included, to avoid adding a dependency to building the docs. + +.. .. automodule:: matplotlib.backends.backend_qt5cairo +.. :members: +.. :undoc-members: +.. :show-inheritance: diff --git a/doc/sphinxext/mock_gui_toolkits.py b/doc/sphinxext/mock_gui_toolkits.py index dea4a91b80cb..ab2b98676d8e 100644 --- a/doc/sphinxext/mock_gui_toolkits.py +++ b/doc/sphinxext/mock_gui_toolkits.py @@ -10,108 +10,6 @@ class MyCairoCffi(MagicMock): version_info = (1, 4, 0) -class MyPyQt4(MagicMock): - class QtGui(object): - # PyQt4.QtGui public classes. - # Generated with - # textwrap.fill([name for name in dir(PyQt4.QtGui) - # if isinstance(getattr(PyQt4.QtGui, name), type)]) - _QtGui_public_classes = """\ - Display QAbstractButton QAbstractGraphicsShapeItem - QAbstractItemDelegate QAbstractItemView QAbstractPrintDialog - QAbstractProxyModel QAbstractScrollArea QAbstractSlider - QAbstractSpinBox QAbstractTextDocumentLayout QAction QActionEvent - QActionGroup QApplication QBitmap QBoxLayout QBrush QButtonGroup - QCalendarWidget QCheckBox QClipboard QCloseEvent QColor QColorDialog - QColumnView QComboBox QCommandLinkButton QCommonStyle QCompleter - QConicalGradient QContextMenuEvent QCursor QDataWidgetMapper QDateEdit - QDateTimeEdit QDesktopServices QDesktopWidget QDial QDialog - QDialogButtonBox QDirModel QDockWidget QDoubleSpinBox QDoubleValidator - QDrag QDragEnterEvent QDragLeaveEvent QDragMoveEvent QDropEvent - QErrorMessage QFileDialog QFileIconProvider QFileOpenEvent - QFileSystemModel QFocusEvent QFocusFrame QFont QFontComboBox - QFontDatabase QFontDialog QFontInfo QFontMetrics QFontMetricsF - QFormLayout QFrame QGesture QGestureEvent QGestureRecognizer QGlyphRun - QGradient QGraphicsAnchor QGraphicsAnchorLayout QGraphicsBlurEffect - QGraphicsColorizeEffect QGraphicsDropShadowEffect QGraphicsEffect - QGraphicsEllipseItem QGraphicsGridLayout QGraphicsItem - QGraphicsItemAnimation QGraphicsItemGroup QGraphicsLayout - QGraphicsLayoutItem QGraphicsLineItem QGraphicsLinearLayout - QGraphicsObject QGraphicsOpacityEffect QGraphicsPathItem - QGraphicsPixmapItem QGraphicsPolygonItem QGraphicsProxyWidget - QGraphicsRectItem QGraphicsRotation QGraphicsScale QGraphicsScene - QGraphicsSceneContextMenuEvent QGraphicsSceneDragDropEvent - QGraphicsSceneEvent QGraphicsSceneHelpEvent QGraphicsSceneHoverEvent - QGraphicsSceneMouseEvent QGraphicsSceneMoveEvent - QGraphicsSceneResizeEvent QGraphicsSceneWheelEvent - QGraphicsSimpleTextItem QGraphicsTextItem QGraphicsTransform - QGraphicsView QGraphicsWidget QGridLayout QGroupBox QHBoxLayout - QHeaderView QHelpEvent QHideEvent QHoverEvent QIcon QIconDragEvent - QIconEngine QIconEngineV2 QIdentityProxyModel QImage QImageIOHandler - QImageReader QImageWriter QInputContext QInputContextFactory - QInputDialog QInputEvent QInputMethodEvent QIntValidator QItemDelegate - QItemEditorCreatorBase QItemEditorFactory QItemSelection - QItemSelectionModel QItemSelectionRange QKeyEvent QKeyEventTransition - QKeySequence QLCDNumber QLabel QLayout QLayoutItem QLineEdit - QLinearGradient QListView QListWidget QListWidgetItem QMainWindow - QMatrix QMatrix2x2 QMatrix2x3 QMatrix2x4 QMatrix3x2 QMatrix3x3 - QMatrix3x4 QMatrix4x2 QMatrix4x3 QMatrix4x4 QMdiArea QMdiSubWindow - QMenu QMenuBar QMessageBox QMimeSource QMouseEvent - QMouseEventTransition QMoveEvent QMovie QPageSetupDialog QPaintDevice - QPaintEngine QPaintEngineState QPaintEvent QPainter QPainterPath - QPainterPathStroker QPalette QPanGesture QPen QPicture QPictureIO - QPinchGesture QPixmap QPixmapCache QPlainTextDocumentLayout - QPlainTextEdit QPolygon QPolygonF QPrintDialog QPrintEngine - QPrintPreviewDialog QPrintPreviewWidget QPrinter QPrinterInfo - QProgressBar QProgressDialog QProxyModel QPushButton QPyTextObject - QQuaternion QRadialGradient QRadioButton QRawFont QRegExpValidator - QRegion QResizeEvent QRubberBand QScrollArea QScrollBar - QSessionManager QShortcut QShortcutEvent QShowEvent QSizeGrip - QSizePolicy QSlider QSortFilterProxyModel QSound QSpacerItem QSpinBox - QSplashScreen QSplitter QSplitterHandle QStackedLayout QStackedWidget - QStandardItem QStandardItemModel QStaticText QStatusBar - QStatusTipEvent QStringListModel QStyle QStyleFactory QStyleHintReturn - QStyleHintReturnMask QStyleHintReturnVariant QStyleOption - QStyleOptionButton QStyleOptionComboBox QStyleOptionComplex - QStyleOptionDockWidget QStyleOptionDockWidgetV2 QStyleOptionFocusRect - QStyleOptionFrame QStyleOptionFrameV2 QStyleOptionFrameV3 - QStyleOptionGraphicsItem QStyleOptionGroupBox QStyleOptionHeader - QStyleOptionMenuItem QStyleOptionProgressBar QStyleOptionProgressBarV2 - QStyleOptionRubberBand QStyleOptionSizeGrip QStyleOptionSlider - QStyleOptionSpinBox QStyleOptionTab QStyleOptionTabBarBase - QStyleOptionTabBarBaseV2 QStyleOptionTabV2 QStyleOptionTabV3 - QStyleOptionTabWidgetFrame QStyleOptionTabWidgetFrameV2 - QStyleOptionTitleBar QStyleOptionToolBar QStyleOptionToolBox - QStyleOptionToolBoxV2 QStyleOptionToolButton QStyleOptionViewItem - QStyleOptionViewItemV2 QStyleOptionViewItemV3 QStyleOptionViewItemV4 - QStylePainter QStyledItemDelegate QSwipeGesture QSyntaxHighlighter - QSystemTrayIcon QTabBar QTabWidget QTableView QTableWidget - QTableWidgetItem QTableWidgetSelectionRange QTabletEvent - QTapAndHoldGesture QTapGesture QTextBlock QTextBlockFormat - QTextBlockGroup QTextBlockUserData QTextBrowser QTextCharFormat - QTextCursor QTextDocument QTextDocumentFragment QTextDocumentWriter - QTextEdit QTextFormat QTextFragment QTextFrame QTextFrameFormat - QTextImageFormat QTextInlineObject QTextItem QTextLayout QTextLength - QTextLine QTextList QTextListFormat QTextObject QTextObjectInterface - QTextOption QTextTable QTextTableCell QTextTableCellFormat - QTextTableFormat QTimeEdit QToolBar QToolBox QToolButton QToolTip - QTouchEvent QTransform QTreeView QTreeWidget QTreeWidgetItem - QTreeWidgetItemIterator QUndoCommand QUndoGroup QUndoStack QUndoView - QVBoxLayout QValidator QVector2D QVector3D QVector4D QWhatsThis - QWhatsThisClickedEvent QWheelEvent QWidget QWidgetAction QWidgetItem - QWindowStateChangeEvent QWizard QWizardPage QWorkspace - QX11EmbedContainer QX11EmbedWidget QX11Info - """ - for _name in _QtGui_public_classes.split(): - locals()[_name] = type(_name, (), {}) - del _name - - -class MySip(MagicMock): - def getapi(*args): - return 1 - - class MyWX(MagicMock): class Panel(object): pass @@ -127,8 +25,6 @@ class Frame(object): def setup(app): sys.modules['cairocffi'] = MyCairoCffi() - sys.modules['PyQt4'] = MyPyQt4() - sys.modules['sip'] = MySip() sys.modules['wx'] = MyWX() sys.modules['wxversion'] = MagicMock() diff --git a/lib/matplotlib/backends/qt_compat.py b/lib/matplotlib/backends/qt_compat.py index bb206c9ed3eb..d0b71be4ea91 100644 --- a/lib/matplotlib/backends/qt_compat.py +++ b/lib/matplotlib/backends/qt_compat.py @@ -1,224 +1,166 @@ -""" A Qt API selector that can be used to switch between PyQt and PySide. +""" +Qt binding and backend selector. + +The selection logic is as follows: +- if any of PyQt5, PySide2, PyQt4 or PySide have already been imported + (checked in that order), use it; +- otherwise, if the QT_API environment variable (used by Enthought) is + set, use it to determine which binding to use (but do not change the + backend based on it; i.e. if the Qt4Agg backend is requested but QT_API + is set to "pyqt5", then actually use Qt4 with the binding specified by + ``rcParams["backend.qt4"]``; +- otherwise, use whatever the rcParams indicate. """ from __future__ import (absolute_import, division, print_function, unicode_literals) import six +from distutils.version import LooseVersion import os -import logging import sys -from matplotlib import rcParams - -_log = logging.getLogger(__name__) - -# Available APIs. -QT_API_PYQT = 'PyQt4' # API is not set here; Python 2.x default is V 1 -QT_API_PYQTv2 = 'PyQt4v2' # forced to Version 2 API -QT_API_PYSIDE = 'PySide' # only supports Version 2 API -QT_API_PYQT5 = 'PyQt5' # use PyQt5 API; Version 2 with module shim -QT_API_PYSIDE2 = 'PySide2' # Version 2 API with module shim -ETS = dict(pyqt=(QT_API_PYQTv2, 4), pyside=(QT_API_PYSIDE, 4), - pyqt5=(QT_API_PYQT5, 5), pyside2=(QT_API_PYSIDE2, 5)) -# ETS is a dict of env variable to (QT_API, QT_MAJOR_VERSION) -# If the ETS QT_API environment variable is set, use it, but only -# if the varible if of the same major QT version. Note that -# ETS requires the version 2 of PyQt4, which is not the platform -# default for Python 2.x. +from matplotlib import rcParams +QT_API_PYQT5 = "PyQt5" +QT_API_PYSIDE2 = "PySide2" +QT_API_PYQTv2 = "PyQt4v2" +QT_API_PYSIDE = "PySide" +QT_API_PYQT = "PyQt4" # Use the old sip v1 API (Py3 defaults to v2). QT_API_ENV = os.environ.get('QT_API') - -if rcParams['backend'] == 'Qt5Agg': - QT_RC_MAJOR_VERSION = 5 -elif rcParams['backend'] == 'Qt4Agg': - QT_RC_MAJOR_VERSION = 4 +# First, check if anything is already imported. +if "PyQt5" in sys.modules: + QT_API = QT_API_PYQT5 + dict.__setitem__(rcParams, "backend.qt5", QT_API) +elif "PySide2" in sys.modules: + QT_API = QT_API_PYSIDE2 + dict.__setitem__(rcParams, "backend.qt5", QT_API) +elif "PyQt4" in sys.modules: + QT_API = QT_API_PYQTv2 + dict.__setitem__(rcParams, "backend.qt4", QT_API) +elif "PySide" in sys.modules: + QT_API = QT_API_PYSIDE + dict.__setitem__(rcParams, "backend.qt4", QT_API) +# Otherwise, check the QT_API environment variable (from Enthought). This can +# only override the binding, not the backend (in other words, we check that the +# requested backend actually matches). +elif rcParams["backend"] == "Qt5Agg": + if QT_API_ENV == "pyqt5": + dict.__setitem__(rcParams, "backend.qt5", QT_API_PYQT5) + elif QT_API_ENV == "pyside2": + dict.__setitem__(rcParams, "backend.qt5", QT_API_PYSIDE2) + QT_API = dict.__getitem__(rcParams, "backend.qt5") +elif rcParams["backend"] == "Qt4Agg": + if QT_API_ENV == "pyqt4": + dict.__setitem__(rcParams, "backend.qt4", QT_API_PYQTv2) + elif QT_API_ENV == "pyside": + dict.__setitem__(rcParams, "backend.qt4", QT_API_PYSIDE) + QT_API = dict.__getitem__(rcParams, "backend.qt4") +# A non-Qt backend was selected but we still got there (possible, e.g., when +# fully manually embedding Matplotlib in a Qt app without using pyplot). else: - # A different backend was specified, but we still got here because a Qt - # related file was imported. This is allowed, so lets try and guess - # what we should be using. - if "PyQt4" in sys.modules or "PySide" in sys.modules: - # PyQt4 or PySide is actually used. - QT_RC_MAJOR_VERSION = 4 - else: - # This is a fallback: PyQt5 - QT_RC_MAJOR_VERSION = 5 + QT_API = None -QT_API = None -# check if any binding is already imported, if so silently ignore the -# rcparams/ENV settings and use what ever is already imported. -if 'PySide' in sys.modules: - # user has imported PySide before importing mpl - QT_API = QT_API_PYSIDE +def _setup_pyqt5(): + global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName -if 'PySide2' in sys.modules: - # user has imported PySide before importing mpl - QT_API = QT_API_PYSIDE2 + if QT_API == QT_API_PYQT5: + from PyQt5 import QtCore, QtGui, QtWidgets + __version__ = QtCore.PYQT_VERSION_STR + QtCore.Signal = QtCore.pyqtSignal + QtCore.Slot = QtCore.pyqtSlot + QtCore.Property = QtCore.pyqtProperty + elif QT_API == QT_API_PYSIDE2: + from PySide2 import QtCore, QtGui, QtWidgets, __version__ + else: + raise ValueError("Unexpected value for the 'backend.qt5' rcparam") + _getSaveFileName = QtWidgets.QFileDialog.getSaveFileName -if 'PyQt4' in sys.modules: - # user has imported PyQt4 before importing mpl - # this case also handles the PyQt4v2 case as once sip is imported - # the API versions can not be changed so do not try - QT_API = QT_API_PYQT + def is_pyqt5(): + return True -if 'PyQt5' in sys.modules: - # the user has imported PyQt5 before importing mpl - QT_API = QT_API_PYQT5 -if (QT_API_ENV is not None) and QT_API is None: - try: - QT_ENV_MAJOR_VERSION = ETS[QT_API_ENV][1] - except KeyError: - raise RuntimeError( - ('Unrecognized environment variable %r, valid values are:' - ' %r, %r, %r or %r' - % (QT_API_ENV, 'pyqt', 'pyside', 'pyqt5', 'pyside2'))) - if QT_ENV_MAJOR_VERSION == QT_RC_MAJOR_VERSION: - # Only if backend and env qt major version are - # compatible use the env variable. - QT_API = ETS[QT_API_ENV][0] - -_fallback_to_qt4 = False -if QT_API is None: - # No ETS environment or incompatible so use rcParams. - if rcParams['backend'] == 'Qt5Agg': - QT_API = QT_API_PYQT5 - elif rcParams['backend'] == 'Qt4Agg': - QT_API = QT_API_PYQT - else: - # A non-Qt backend was specified, no version of the Qt - # bindings is imported, but we still got here because a Qt - # related file was imported. This is allowed, fall back to Qt5 - # using which ever binding the rparams ask for. - _fallback_to_qt4 = True - QT_API = QT_API_PYQT5 - -# We will define an appropriate wrapper for the differing versions -# of file dialog. -_getSaveFileName = None - -# Flag to check if sip could be imported -_sip_imported = False - -# Now perform the imports. -if QT_API in (QT_API_PYQT, QT_API_PYQTv2): - try: - import sip - _sip_imported = True - except ImportError: - # Try using PySide - if QT_RC_MAJOR_VERSION == 5: - QT_API = QT_API_PYSIDE2 - else: - QT_API = QT_API_PYSIDE - cond = ("Could not import sip; falling back on PySide\n" - "in place of PyQt4 or PyQt5.\n") - _log.info(cond) +def _setup_pyqt4(): + global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName -if _sip_imported: - if QT_API == QT_API_PYQTv2: - if QT_API_ENV == 'pyqt': - cond = ("Found 'QT_API=pyqt' environment variable. " - "Setting PyQt4 API accordingly.\n") - else: - cond = "PyQt API v2 specified." + def _setup_pyqt4_internal(api): + global QtCore, QtGui, QtWidgets, \ + __version__, is_pyqt5, _getSaveFileName + # List of incompatible APIs: + # http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html + _sip_apis = ["QDate", "QDateTime", "QString", "QTextStream", "QTime", + "QUrl", "QVariant"] try: - sip.setapi('QString', 2) - except: - res = 'QString API v2 specification failed. Defaulting to v1.' - _log.info(cond + res) - # condition has now been reported, no need to repeat it: - cond = "" - try: - sip.setapi('QVariant', 2) - except: - res = 'QVariant API v2 specification failed. Defaulting to v1.' - _log.info(cond + res) - -if QT_API == QT_API_PYQT5: - try: - from PyQt5 import QtCore, QtGui, QtWidgets - _getSaveFileName = QtWidgets.QFileDialog.getSaveFileName - except ImportError: - if _fallback_to_qt4: - # fell through, tried PyQt5, failed fall back to PyQt4 - QT_API = QT_API_PYQT - QT_RC_MAJOR_VERSION = 4 + import sip + except ImportError: + pass else: - raise - -if _sip_imported: - # needs to be if so we can re-test the value of QT_API which may - # have been changed in the above if block - if QT_API in [QT_API_PYQT, QT_API_PYQTv2]: # PyQt4 API + for _sip_api in _sip_apis: + try: + sip.setapi(_sip_api, api) + except ValueError: + pass from PyQt4 import QtCore, QtGui - - try: - if sip.getapi("QString") > 1: - # Use new getSaveFileNameAndFilter() - _getSaveFileName = QtGui.QFileDialog.getSaveFileNameAndFilter - else: - - # Use old getSaveFileName() - def _getSaveFileName(*args, **kwargs): - return (QtGui.QFileDialog.getSaveFileName(*args, **kwargs), - None) - - except (AttributeError, KeyError): - - # call to getapi() can fail in older versions of sip - def _getSaveFileName(*args, **kwargs): - return QtGui.QFileDialog.getSaveFileName(*args, **kwargs), None - - -if QT_API == QT_API_PYSIDE2: - try: - from PySide2 import QtCore, QtGui, QtWidgets, __version__ - _getSaveFileName = QtWidgets.QFileDialog.getSaveFileName - except ImportError: - # tried PySide2, failed, fall back to PySide - QT_RC_MAJOR_VERSION = 4 - QT_API = QT_API_PYSIDE - -if QT_API == QT_API_PYSIDE: # try importing pyside - try: - from PySide import QtCore, QtGui, __version__, __version_info__ - except ImportError: - raise ImportError( - "Matplotlib qt-based backends require an external PyQt4, PyQt5,\n" - "PySide or PySide2 package to be installed, but it was not found.") - - if __version_info__ < (1, 0, 3): - raise ImportError( - "Matplotlib backend_qt4 and backend_qt4agg require PySide >=1.0.3") - - _getSaveFileName = QtGui.QFileDialog.getSaveFileName - - -if QT_API in (QT_API_PYQT, QT_API_PYQTv2, QT_API_PYQT5): - # Alias PyQt-specific functions for PySide compatibility. - QtCore.Signal = QtCore.pyqtSignal - try: + __version__ = QtCore.PYQT_VERSION_STR + # PyQt 4.6 introduced getSaveFileNameAndFilter: + # https://riverbankcomputing.com/news/pyqt-46 + if __version__ < LooseVersion("4.6"): + raise ImportError("PyQt<4.6 is not supported") + QtCore.Signal = QtCore.pyqtSignal QtCore.Slot = QtCore.pyqtSlot - except AttributeError: - # Not a perfect match but works in simple cases - QtCore.Slot = QtCore.pyqtSignature - - QtCore.Property = QtCore.pyqtProperty - __version__ = QtCore.PYQT_VERSION_STR - -# Apply shim to Qt4 APIs to make them look like Qt5 -if QT_API in (QT_API_PYQT, QT_API_PYQTv2, QT_API_PYSIDE): - '''Import all used QtGui objects into QtWidgets - - Here I've opted to simple copy QtGui into QtWidgets as that - achieves the same result as copying over the objects, and will - continue to work if other objects are used. + QtCore.Property = QtCore.pyqtProperty + _getSaveFileName = QtGui.QFileDialog.getSaveFileNameAndFilter - ''' + if QT_API == QT_API_PYQTv2: + _setup_pyqt4_internal(api=2) + elif QT_API == QT_API_PYSIDE: + from PySide import QtCore, QtGui, __version__, __version_info__ + # PySide 1.0.3 fixed the following: + # https://srinikom.github.io/pyside-bz-archive/809.html + if __version_info__ < (1, 0, 3): + raise ImportError("PySide<1.0.3 is not supported") + _getSaveFileName = QtGui.QFileDialog.getSaveFileName + elif QT_API == QT_API_PYQT: + _setup_pyqt4_internal(api=1) + else: + raise ValueError("Unexpected value for the 'backend.qt4' rcparam") QtWidgets = QtGui + def is_pyqt5(): + return False + + +if QT_API in [QT_API_PYQT5, QT_API_PYSIDE2]: + _setup_pyqt5() +elif QT_API in [QT_API_PYQTv2, QT_API_PYSIDE, QT_API_PYQT]: + _setup_pyqt4() +elif QT_API is None: + if rcParams["backend"] == "Qt4Agg": + _candidates = [(_setup_pyqt4, QT_API_PYQTv2), + (_setup_pyqt4, QT_API_PYSIDE), + (_setup_pyqt4, QT_API_PYQT), + (_setup_pyqt5, QT_API_PYQT5), + (_setup_pyqt5, QT_API_PYSIDE2)] + else: + _candidates = [(_setup_pyqt5, QT_API_PYQT5), + (_setup_pyqt5, QT_API_PYSIDE2), + (_setup_pyqt4, QT_API_PYQTv2), + (_setup_pyqt4, QT_API_PYSIDE), + (_setup_pyqt4, QT_API_PYQT)] + for _setup, QT_API in _candidates: + try: + _setup() + except ImportError: + continue + break + else: + raise ImportError("Failed to import any qt binding") +else: # We should not get there. + raise AssertionError("Unexpected QT_API: {}".format(QT_API)) -def is_pyqt5(): - return QT_API == QT_API_PYQT5 + +# These globals are only defined for backcompatibilty purposes. +ETS = dict(pyqt=(QT_API_PYQTv2, 4), pyside=(QT_API_PYSIDE, 4), + pyqt5=(QT_API_PYQT5, 5), pyside2=(QT_API_PYSIDE2, 5)) +QT_RC_MAJOR_VERSION = 5 if is_pyqt5() else 4 From faf9684bbd1ec2a7cca7251f2d4c93382eedf6a4 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 14 May 2018 15:30:21 -0400 Subject: [PATCH 02/12] Merge pull request #11047 from jklymak/fix-image-respect-norm-limits FIX: image respect norm limits w/ None Conflicts: lib/matplotlib/image.py - keep changes backported from master. Looks like conflict was due to some white-space clean up done on master. --- lib/matplotlib/image.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index f2a7280af553..3ea0cb70d3e1 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -401,26 +401,27 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, # float64's ability to represent changes. Applying # a norm first would be good, but ruins the interpolation # of over numbers. - if self.norm.vmin is not None and self.norm.vmax is not None: - dv = (np.float64(self.norm.vmax) - - np.float64(self.norm.vmin)) - vmid = self.norm.vmin + dv / 2 - newmin = vmid - dv * 1.e7 - if newmin < a_min: - newmin = None - else: - a_min = np.float64(newmin) - newmax = vmid + dv * 1.e7 - if newmax > a_max: - newmax = None - else: - a_max = np.float64(newmax) - if newmax is not None or newmin is not None: - A_scaled = np.clip(A_scaled, newmin, newmax) + self.norm.autoscale_None(A) + dv = (np.float64(self.norm.vmax) - + np.float64(self.norm.vmin)) + vmid = self.norm.vmin + dv / 2 + fact = 1e7 if scaled_dtype == np.float64 else 1e4 + newmin = vmid - dv * fact + if newmin < a_min: + newmin = None + else: + a_min = np.float64(newmin) + newmax = vmid + dv * fact + if newmax > a_max: + newmax = None + else: + a_max = np.float64(newmax) + if newmax is not None or newmin is not None: + A_scaled = np.clip(A_scaled, newmin, newmax) A_scaled -= a_min # a_min and a_max might be ndarray subclasses so use - # asscalar to ensure they are scalars to avoid errors + # asscalar to avoid errors a_min = np.asscalar(a_min.astype(scaled_dtype)) a_max = np.asscalar(a_max.astype(scaled_dtype)) From 636a06d154eb3fc15ab974410e93543f59927efc Mon Sep 17 00:00:00 2001 From: Paul Hobson Date: Wed, 18 Apr 2018 00:11:49 -0700 Subject: [PATCH 03/12] Merge pull request #11071 from dstansby/hist-scaling Add note about hist2d resetting axis limits Conflicts: lib/matplotlib/axes/_axes.py - kept master branch version of docstrings --- lib/matplotlib/axes/_axes.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 6959de8d518c..e2c293114ca6 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -6855,21 +6855,21 @@ def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, - If int, the number of bins for the two dimensions (nx=ny=bins). - - If [int, int], the number of bins in each dimension + - If ``[int, int]``, the number of bins in each dimension (nx, ny = bins). - If array_like, the bin edges for the two dimensions (x_edges=y_edges=bins). - - If [array, array], the bin edges in each dimension + - If ``[array, array]``, the bin edges in each dimension (x_edges, y_edges = bins). The default value is 10. range : array_like shape(2, 2), optional, default: None The leftmost and rightmost edges of the bins along each dimension - (if not specified explicitly in the bins parameters): [[xmin, - xmax], [ymin, ymax]]. All values outside of this range will be + (if not specified explicitly in the bins parameters): ``[[xmin, + xmax], [ymin, ymax]]``. All values outside of this range will be considered outliers and not tallied in the histogram. normed : boolean, optional, default: False @@ -6902,32 +6902,33 @@ def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, Other Parameters ---------------- - cmap : {Colormap, string}, optional - A :class:`matplotlib.colors.Colormap` instance. If not set, use rc - settings. + cmap : Colormap or str, optional + A `.colors.Colormap` instance. If not set, use rc settings. norm : Normalize, optional - A :class:`matplotlib.colors.Normalize` instance is used to + A `.colors.Normalize` instance is used to scale luminance data to ``[0, 1]``. If not set, defaults to - ``Normalize()``. + `.colors.Normalize()`. - vmin/vmax : {None, scalar}, optional - Arguments passed to the `Normalize` instance. + vmin/vmax : None or scalar, optional + Arguments passed to the `~.colors.Normalize` instance. alpha : ``0 <= scalar <= 1`` or ``None``, optional The alpha blending value. See also -------- - hist : 1D histogram + hist : 1D histogram plotting Notes ----- - Rendering the histogram with a logarithmic color scale is - accomplished by passing a :class:`colors.LogNorm` instance to - the *norm* keyword argument. Likewise, power-law normalization - (similar in effect to gamma correction) can be accomplished with - :class:`colors.PowerNorm`. + - Currently ``hist2d`` calculates it's own axis limits, and any limits + previously set are ignored. + - Rendering the histogram with a logarithmic color scale is + accomplished by passing a `.colors.LogNorm` instance to the *norm* + keyword argument. Likewise, power-law normalization (similar + in effect to gamma correction) can be accomplished with + `.colors.PowerNorm`. """ h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range, From 278ee470f542d0986f086545dad041afb0553420 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Mon, 19 Mar 2018 01:26:31 +0100 Subject: [PATCH 04/12] Merge pull request #10833 from anntzer/marker-antialiasing Propagate marker antialias setting to GraphicsContext. --- lib/matplotlib/lines.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index 984f5b025f4b..53a50a70b4b8 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -800,6 +800,7 @@ def draw(self, renderer): gc.set_alpha(rgbaFace[3]) else: gc.set_alpha(self.get_alpha()) + gc.set_antialiased(self._antialiased) marker = self._marker tpath, affine = transf_path.get_transformed_points_and_affine() From 393c862f12fa14b853b66040b59e5dc111d97c5d Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 29 Apr 2018 20:20:03 -0400 Subject: [PATCH 05/12] Merge pull request #11105 from anntzer/markerfacecolor-none-alpha FIX: When drawing markers, don't set the GraphicsContext alpha. Conflicts: lib/matplotlib/lines.py - keep aliases (which are implemented automatically on master) explicitly in code --- lib/matplotlib/backends/backend_ps.py | 5 +- lib/matplotlib/lines.py | 50 +- .../test_axes/errorbar_mixed.svg | 700 +++++++++--------- .../test_axes/rgba_markers.svg | 204 ++--- .../baseline_images/test_axes/test_alpha.svg | 332 ++++----- lib/matplotlib/tests/test_axes.py | 14 + 6 files changed, 667 insertions(+), 638 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 8e8deae4d700..5e475101d3b7 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -537,7 +537,10 @@ def draw_markers( ps_cmd = ['/o {', 'gsave', 'newpath', 'translate'] # don't want the translate to be global lw = gc.get_linewidth() - stroke = lw != 0.0 + alpha = (gc.get_alpha() + if gc.get_forced_alpha() or len(gc.get_rgb()) == 3 + else gc.get_rgb()[3]) + stroke = lw > 0 and alpha > 0 if stroke: ps_cmd.append('%.1f setlinewidth' % lw) jint = gc.get_joinstyle() diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index 53a50a70b4b8..b885ec1713dc 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -758,9 +758,8 @@ def draw(self, renderer): gc = renderer.new_gc() self._set_gc_clip(gc) - ln_color_rgba = self._get_rgba_ln_color() - gc.set_foreground(ln_color_rgba, isRGBA=True) - gc.set_alpha(ln_color_rgba[3]) + lc_rgba = mcolors.to_rgba(self._color, self._alpha) + gc.set_foreground(lc_rgba, isRGBA=True) gc.set_antialiased(self._antialiased) gc.set_linewidth(self._linewidth) @@ -784,24 +783,23 @@ def draw(self, renderer): if self._marker and self._markersize > 0: gc = renderer.new_gc() self._set_gc_clip(gc) - rgbaFace = self._get_rgba_face() - rgbaFaceAlt = self._get_rgba_face(alt=True) - edgecolor = self.get_markeredgecolor() - if cbook._str_lower_equal(edgecolor, "none"): - gc.set_linewidth(0) - gc.set_foreground(rgbaFace, isRGBA=True) - else: - gc.set_foreground(edgecolor) - gc.set_linewidth(self._markeredgewidth) - mec = self._markeredgecolor - if (cbook._str_equal(mec, "auto") - and not cbook._str_lower_equal( - self.get_markerfacecolor(), "none")): - gc.set_alpha(rgbaFace[3]) - else: - gc.set_alpha(self.get_alpha()) + gc.set_linewidth(self._markeredgewidth) gc.set_antialiased(self._antialiased) + ec_rgba = mcolors.to_rgba( + self.get_markeredgecolor(), self._alpha) + fc_rgba = mcolors.to_rgba( + self._get_markerfacecolor(), self._alpha) + fcalt_rgba = mcolors.to_rgba( + self._get_markerfacecolor(alt=True), self._alpha) + # If the edgecolor is "auto", it is set according to the *line* + # color but inherits the alpha value of the *face* color, if any. + if (cbook._str_equal(self._markeredgecolor, "auto") + and not cbook._str_lower_equal( + self.get_markerfacecolor(), "none")): + ec_rgba = ec_rgba[:3] + (fc_rgba[3],) + gc.set_foreground(ec_rgba, isRGBA=True) + marker = self._marker tpath, affine = transf_path.get_transformed_points_and_affine() if len(tpath.vertices): @@ -831,22 +829,15 @@ def draw(self, renderer): renderer.draw_markers(gc, marker_path, marker_trans, subsampled, affine.frozen(), - rgbaFace) + fc_rgba) alt_marker_path = marker.get_alt_path() if alt_marker_path: alt_marker_trans = marker.get_alt_transform() alt_marker_trans = alt_marker_trans.scale(w) - if (cbook._str_equal(mec, "auto") - and not cbook._str_lower_equal( - self.get_markerfacecoloralt(), "none")): - gc.set_alpha(rgbaFaceAlt[3]) - else: - gc.set_alpha(self.get_alpha()) - renderer.draw_markers( gc, alt_marker_path, alt_marker_trans, subsampled, - affine.frozen(), rgbaFaceAlt) + affine.frozen(), fcalt_rgba) gc.restore() @@ -891,8 +882,7 @@ def _get_markerfacecolor(self, alt=False): fc = self._markerfacecoloralt else: fc = self._markerfacecolor - - if (isinstance(fc, six.string_types) and fc.lower() == 'auto'): + if cbook._str_lower_equal(fc, 'auto'): if self.get_fillstyle() == 'none': return 'none' else: diff --git a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg index 61da0aca346e..7302d4e74273 100644 --- a/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg +++ b/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg @@ -1,7 +1,7 @@ - + - - - - - - - - - + + + + + + + + + @@ -132,68 +132,68 @@ L 274.909091 43.2 +" id="m368fc901b1" style="stroke:#000000;stroke-width:0.5;"/> - + +" id="mc63e59a608" style="stroke:#000000;stroke-width:0.5;"/> - + - + - + - + - + - + - + - + - + @@ -204,20 +204,20 @@ L 0 4 +" id="m556f96d829" style="stroke:#000000;stroke-width:0.5;"/> - + +" id="m27e32ca04a" style="stroke:#000000;stroke-width:0.5;"/> - + @@ -238,6 +238,7 @@ Q 39.453125 6.390625 43.28125 13.890625 Q 47.125 21.390625 47.125 36.375 Q 47.125 51.421875 43.28125 58.90625 Q 39.453125 66.40625 31.78125 66.40625 +z M 31.78125 74.21875 Q 44.046875 74.21875 50.515625 64.515625 Q 56.984375 54.828125 56.984375 36.375 @@ -247,6 +248,7 @@ Q 19.53125 -1.421875 13.0625 8.265625 Q 6.59375 17.96875 6.59375 36.375 Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 +z " id="DejaVuSans-30"/> - + - + @@ -310,12 +312,12 @@ z - + - + @@ -330,12 +332,12 @@ z - + - + @@ -365,12 +367,12 @@ z - + - + @@ -411,6 +413,7 @@ Q 5.515625 40.234375 12.765625 48.109375 Q 20.015625 56 32.328125 56 Q 43.359375 56 49.78125 48.890625 Q 56.203125 41.796875 56.203125 29.59375 +z M 47.21875 32.234375 Q 47.125 39.59375 43.09375 43.984375 Q 39.0625 48.390625 32.421875 48.390625 @@ -484,6 +487,7 @@ Q 5.8125 47.609375 11.28125 51.796875 Q 16.75 56 26.8125 56 Q 31.78125 56 36.171875 55.265625 Q 40.578125 54.546875 44.28125 53.078125 +z " id="DejaVuSans-73"/> @@ -591,28 +597,28 @@ z " style="fill:#ffffff;"/> - - - - - - - - @@ -620,29 +626,29 @@ L 472.224823 195.998601 +" id="m454add2b76" style="stroke:#0000ff;stroke-opacity:0.4;stroke-width:0.5;"/> - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + @@ -657,17 +663,17 @@ C -2.683901 -1.55874 -3 -0.795609 -3 0 C -3 0.795609 -2.683901 1.55874 -2.12132 2.12132 C -1.55874 2.683901 -0.795609 3 0 3 z -" id="mb7d77fda26" style="stroke:#000000;stroke-width:0.5;"/> +" id="m1bffda5d1f" style="stroke:#000000;stroke-opacity:0.4;stroke-width:0.5;"/> - - - - - - - - - + + + + + + + + + @@ -694,60 +700,60 @@ L 518.4 43.2 - + - + - + - + - + - + - + - + - + - + @@ -756,12 +762,12 @@ L 518.4 43.2 - + - + @@ -776,12 +782,12 @@ L 518.4 43.2 - + - + @@ -809,6 +815,7 @@ Q 53.21875 48.921875 51.53125 44.890625 Q 49.859375 40.875 45.40625 35.40625 Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 +z " id="DejaVuSans-32"/> @@ -821,12 +828,12 @@ Q 31.109375 20.453125 19.1875 8.296875 - + - + @@ -860,12 +867,12 @@ z - + - + @@ -880,6 +887,7 @@ Q 39.65625 6.390625 43.53125 10.953125 Q 47.40625 15.53125 47.40625 23.390625 Q 47.40625 31.296875 43.53125 35.828125 Q 39.65625 40.375 33.015625 40.375 +z M 52.59375 71.296875 L 52.59375 62.3125 Q 48.875 64.0625 45.09375 64.984375 @@ -898,6 +906,7 @@ Q 6.984375 53.65625 15.1875 63.9375 Q 23.390625 74.21875 37.203125 74.21875 Q 40.921875 74.21875 44.703125 73.484375 Q 48.484375 72.75 52.59375 71.296875 +z " id="DejaVuSans-36"/> @@ -910,12 +919,12 @@ Q 48.484375 72.75 52.59375 71.296875 - + - + @@ -930,6 +939,7 @@ Q 38.8125 6.390625 42.859375 10.171875 Q 46.921875 13.96875 46.921875 20.515625 Q 46.921875 27.09375 42.890625 30.859375 Q 38.875 34.625 31.78125 34.625 +z M 21.921875 38.8125 Q 15.578125 40.375 12.03125 44.71875 Q 8.5 49.078125 8.5 55.328125 @@ -947,6 +957,7 @@ Q 19.734375 -1.421875 13.25 4.234375 Q 6.78125 9.90625 6.78125 20.515625 Q 6.78125 27.484375 10.78125 32.3125 Q 14.796875 37.15625 21.921875 38.8125 +z M 18.3125 54.390625 Q 18.3125 48.734375 21.84375 45.5625 Q 25.390625 42.390625 31.78125 42.390625 @@ -956,6 +967,7 @@ Q 45.3125 60.0625 41.71875 63.234375 Q 38.140625 66.40625 31.78125 66.40625 Q 25.390625 66.40625 21.84375 63.234375 Q 18.3125 60.0625 18.3125 54.390625 +z " id="DejaVuSans-38"/> @@ -968,12 +980,12 @@ Q 18.3125 60.0625 18.3125 54.390625 - + - + @@ -1012,6 +1024,7 @@ Q 37.796875 6.203125 41.984375 11.859375 Q 46.1875 17.53125 46.1875 27.296875 Q 46.1875 37.015625 41.984375 42.703125 Q 37.796875 48.390625 30.609375 48.390625 +z M 30.609375 56 Q 42.328125 56 49.015625 48.375 Q 55.71875 40.765625 55.71875 27.296875 @@ -1021,6 +1034,7 @@ Q 18.84375 -1.421875 12.171875 6.21875 Q 5.515625 13.875 5.515625 27.296875 Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 +z " id="DejaVuSans-6f"/> @@ -1160,54 +1178,54 @@ z " style="fill:#ffffff;"/> - - - - - - - - - - - - - - - - @@ -1215,57 +1233,57 @@ L 214.036364 272.060219 +" id="m1981e1242d" style="stroke:#0000ff;stroke-width:0.5;"/> - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + + @@ -1309,12 +1327,12 @@ L 274.909091 231.709091 - + - + @@ -1328,12 +1346,12 @@ L 274.909091 231.709091 - + - + @@ -1346,12 +1364,12 @@ L 274.909091 231.709091 - + - + @@ -1364,12 +1382,12 @@ L 274.909091 231.709091 - + - + @@ -1382,12 +1400,12 @@ L 274.909091 231.709091 - + - + @@ -1402,12 +1420,12 @@ L 274.909091 231.709091 - + - + @@ -1423,12 +1441,12 @@ L 274.909091 231.709091 - + - + @@ -1443,12 +1461,12 @@ L 274.909091 231.709091 - + - + @@ -1463,12 +1481,12 @@ L 274.909091 231.709091 - + - + @@ -1483,12 +1501,12 @@ L 274.909091 231.709091 - + - + @@ -1542,54 +1560,54 @@ z " style="fill:#ffffff;"/> - - - - - - - - - - - - - - - - @@ -1597,70 +1615,70 @@ L 457.527273 284.387119 +" id="mef9c074d9e" style="stroke:#008000;stroke-width:2;"/> - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + +" id="maff64b0a79" style="stroke:#008000;stroke-width:2;"/> - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + @@ -1687,12 +1705,12 @@ L 518.4 231.709091 - + - + @@ -1706,12 +1724,12 @@ L 518.4 231.709091 - + - + @@ -1724,12 +1742,12 @@ L 518.4 231.709091 - + - + @@ -1742,12 +1760,12 @@ L 518.4 231.709091 - + - + @@ -1760,12 +1778,12 @@ L 518.4 231.709091 - + - + @@ -1780,12 +1798,12 @@ L 518.4 231.709091 - + - + @@ -1809,12 +1827,12 @@ z - + - + @@ -1830,12 +1848,12 @@ z - + - + @@ -1850,12 +1868,12 @@ z - + - + @@ -1872,296 +1890,296 @@ z +" id="mb12535d6a8" style="stroke:#000000;stroke-width:0.5;"/> - + +" id="m8a2e629618" style="stroke:#000000;stroke-width:0.5;"/> - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2212,6 +2230,7 @@ Q 5.515625 40.1875 11.734375 48.09375 Q 17.96875 56 27.875 56 Q 33.9375 56 38.25 53.625 Q 42.578125 51.265625 45.40625 46.390625 +z M 14.796875 27.296875 Q 14.796875 17.390625 18.875 11.75 Q 22.953125 6.109375 30.078125 6.109375 @@ -2221,6 +2240,7 @@ Q 45.40625 37.203125 41.296875 42.84375 Q 37.203125 48.484375 30.078125 48.484375 Q 22.953125 48.484375 18.875 42.84375 Q 14.796875 37.203125 14.796875 27.296875 +z " id="DejaVuSans-64"/> + - + - + - + diff --git a/lib/matplotlib/tests/baseline_images/test_axes/rgba_markers.svg b/lib/matplotlib/tests/baseline_images/test_axes/rgba_markers.svg index a1ff94a96f94..f0b1b2f3fdc1 100644 --- a/lib/matplotlib/tests/baseline_images/test_axes/rgba_markers.svg +++ b/lib/matplotlib/tests/baseline_images/test_axes/rgba_markers.svg @@ -1,7 +1,7 @@ - + - - + + @@ -50,10 +50,10 @@ z L 50 -50 M -50 -50 L 50 50 -" id="m5255e8aef7" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="m2bb53bbd7a" style="stroke:#ff0000;stroke-width:20;"/> - - + + @@ -68,10 +68,10 @@ C -44.731685 -25.978994 -50 -13.260155 -50 0 C -50 13.260155 -44.731685 25.978994 -35.355339 35.355339 C -25.978994 44.731685 -13.260155 50 0 50 z -" id="me1f47d7cf6" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="m774356cf9a" style="stroke:#ff0000;stroke-width:20;"/> - - + + @@ -80,10 +80,10 @@ z L 50 -50 M -50 -50 L 50 50 -" id="m15e5501d3a" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="m081d77a145" style="stroke:#ff0000;stroke-width:20;"/> - - + + @@ -98,10 +98,10 @@ C -44.731685 -25.978994 -50 -13.260155 -50 0 C -50 13.260155 -44.731685 25.978994 -35.355339 35.355339 C -25.978994 44.731685 -13.260155 50 0 50 z -" id="md637c91b3e" style="stroke:#ff0000;stroke-opacity:0.500000;stroke-width:20.000000;"/> +" id="mf98d41f430" style="stroke:#ff0000;stroke-opacity:0.5;stroke-width:20;"/> - - + + @@ -110,10 +110,10 @@ z L 50 -50 M -50 -50 L 50 50 -" id="m4da6bdd7bd" style="stroke:#ff0000;stroke-opacity:0.500000;stroke-width:20.000000;"/> +" id="m1d398718ef" style="stroke:#ff0000;stroke-opacity:0.5;stroke-width:20;"/> - - + + @@ -128,10 +128,10 @@ C -44.731685 -25.978994 -50 -13.260155 -50 0 C -50 13.260155 -44.731685 25.978994 -35.355339 35.355339 C -25.978994 44.731685 -13.260155 50 0 50 z -" id="mc360218c81" style="stroke:#ff0000;stroke-opacity:0.500000;stroke-width:20.000000;"/> +" id="m1b96511c70" style="stroke:#ff0000;stroke-opacity:0.5;stroke-width:20;"/> - - + + @@ -140,10 +140,10 @@ z L 50 -50 M -50 -50 L 50 50 -" id="m06dcee4ca2" style="stroke:#ff0000;stroke-opacity:0.500000;stroke-width:20.000000;"/> +" id="m4fe50dc6c8" style="stroke:#ff0000;stroke-opacity:0.5;stroke-width:20;"/> - - + + @@ -172,80 +172,80 @@ L 274.909091 43.2 +" id="m368fc901b1" style="stroke:#000000;stroke-width:0.5;"/> - + +" id="mc63e59a608" style="stroke:#000000;stroke-width:0.5;"/> - + - + - + - + - + - + - + - + - + - + - + @@ -256,80 +256,80 @@ L 0 4 +" id="m556f96d829" style="stroke:#000000;stroke-width:0.5;"/> - + +" id="m27e32ca04a" style="stroke:#000000;stroke-width:0.5;"/> - + - + - + - + - + - + - + - + - + - + - + @@ -356,10 +356,10 @@ C -44.731685 -25.978994 -50 -13.260155 -50 0 C -50 13.260155 -44.731685 25.978994 -35.355339 35.355339 C -25.978994 44.731685 -13.260155 50 0 50 z -" id="m258ee76e10" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="maf4b7325aa" style="stroke:#ff0000;stroke-opacity:0.2;stroke-width:20;"/> - - + + @@ -368,15 +368,15 @@ z L 50 -50 M -50 -50 L 50 50 -" id="m4cae70e294" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="m7002b850de" style="stroke:#ff0000;stroke-opacity:0.2;stroke-width:20;"/> - - + + - - + + @@ -385,15 +385,15 @@ L 50 50 L 50 -50 M -50 -50 L 50 50 -" id="m105f2a95b9" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="maf7b03c9e5" style="stroke:#ff0000;stroke-opacity:0.2;stroke-width:20;"/> - - + + - - + + @@ -402,15 +402,15 @@ L 50 50 L 50 -50 M -50 -50 L 50 50 -" id="mfa5c6e318e" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="m454cbe1679" style="stroke:#ff0000;stroke-opacity:0.2;stroke-width:20;"/> - - + + - - + + @@ -419,10 +419,10 @@ L 50 50 L 50 -50 M -50 -50 L 50 50 -" id="mfed096623b" style="stroke:#ff0000;stroke-width:20.000000;"/> +" id="m7f6b33c891" style="stroke:#ff0000;stroke-opacity:0.2;stroke-width:20;"/> - - + + @@ -449,72 +449,72 @@ L 518.4 43.2 - + - + - + - + - + - + - + - + - + - + - + - + @@ -523,72 +523,72 @@ L 518.4 43.2 - + - + - + - + - + - + - + - + - + - + - + - + @@ -596,11 +596,11 @@ L 518.4 43.2 - - + + - - + + diff --git a/lib/matplotlib/tests/baseline_images/test_axes/test_alpha.svg b/lib/matplotlib/tests/baseline_images/test_axes/test_alpha.svg index 640dd9d7536a..5f7dd673897e 100644 --- a/lib/matplotlib/tests/baseline_images/test_axes/test_alpha.svg +++ b/lib/matplotlib/tests/baseline_images/test_axes/test_alpha.svg @@ -1,7 +1,7 @@ - + - +" id="mcdcf90c5d1" style="stroke:#000000;stroke-linejoin:miter;stroke-opacity:0.5;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + @@ -253,7 +253,7 @@ z - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +" style="fill:none;stroke:#ff0000;stroke-linecap:square;stroke-opacity:0.5;stroke-width:10;"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +" style="fill:none;stroke:#ff0000;stroke-linecap:square;stroke-opacity:0.5;stroke-width:10;"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - +" style="fill:none;stroke:#ff0000;stroke-linecap:square;stroke-opacity:0.5;stroke-width:10;"/> + @@ -806,7 +806,7 @@ L -4 0 - + diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index e1d66afebfd8..c71aa6bfe844 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -5642,3 +5642,17 @@ def test_empty_errorbar_legend(): def test_plot_columns_cycle_deprecation(): with pytest.warns(MatplotlibDeprecationWarning): plt.plot(np.zeros((2, 2)), np.zeros((2, 3))) + + +def test_markerfacecolor_none_alpha(): + fig1, ax1 = plt.subplots() + ax1.plot(0, "o", mfc="none", alpha=.5) + buf1 = io.BytesIO() + fig1.savefig(buf1) + + fig2, ax2 = plt.subplots() + ax2.plot(0, "o", mfc="w", alpha=.5) + buf2 = io.BytesIO() + fig2.savefig(buf2) + + assert buf1.getvalue() == buf2.getvalue() From 758bfca3917b82817d700290a7a3cefaad520937 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Thu, 17 May 2018 12:07:12 -0700 Subject: [PATCH 06/12] Merge pull request #11262 from mdboom/optional-threading Use dummy_threading if threading not available Conflicts: lib/matplotlib/backends/backend_agg.py - conflicts due to removing __future__ / six on master --- lib/matplotlib/backends/backend_agg.py | 6 +++++- lib/matplotlib/font_manager.py | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index f4e836b2ef14..aff6cddf492d 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -24,7 +24,11 @@ import six -import threading +try: + import threading +except ImportError: + import dummy_threading as threading + import numpy as np from collections import OrderedDict from math import radians, cos, sin diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index b4f14d7a0093..5900fc9b1841 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -48,7 +48,10 @@ import json import os import sys -from threading import Timer +try: + from threading import Timer +except ImportError: + from dummy_threading import Timer import warnings import logging From e5ce40b858c32aa2419598113c2692110babfc72 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 28 May 2018 23:51:28 -0700 Subject: [PATCH 07/12] Merge pull request #11312 from anntzer/rerefs This also backported parts of other PRs making changes to the docs. Replace :ref:`sphx_glr_...` by :doc:`/...`. Conflicts: examples/color/color_cycler.py - deleted, not present on 2.2.x examples/axes_grid1/simple_anchored_artists.py examples/images_contours_and_fields/contour_image.py examples/images_contours_and_fields/quiver_demo.py examples/images_contours_and_fields/quiver_simple_demo.py examples/misc/anchored_artists.py - keep master version --- doc/api/api_changes.rst | 4 +-- doc/api/pyplot_summary.rst | 4 +-- doc/devel/contributing.rst | 2 +- doc/faq/howto_faq.rst | 16 +++++----- doc/faq/installing_faq.rst | 2 +- doc/faq/troubleshooting_faq.rst | 2 +- doc/mpl_toolkits/index.rst | 2 +- doc/mpl_toolkits/mplot3d/index.rst | 2 +- doc/users/dflt_style_changes.rst | 4 +-- doc/users/prev_whats_new/whats_new_0.98.4.rst | 2 +- doc/users/prev_whats_new/whats_new_0.99.rst | 10 +++---- doc/users/prev_whats_new/whats_new_1.0.rst | 4 +-- doc/users/prev_whats_new/whats_new_1.1.rst | 8 ++--- doc/users/prev_whats_new/whats_new_1.2.rst | 2 +- doc/users/prev_whats_new/whats_new_1.4.rst | 6 ++-- doc/users/prev_whats_new/whats_new_1.5.rst | 2 +- doc/users/prev_whats_new/whats_new_2.0.0.rst | 2 +- doc/users/prev_whats_new/whats_new_2.1.0.rst | 2 +- doc/users/shell.rst | 2 +- .../axes_grid1/simple_anchored_artists.py | 4 +++ examples/color/color_cycle_default.py | 2 +- examples/color/color_demo.py | 4 +-- examples/color/named_colors.py | 4 +-- .../contour_demo.py | 5 ++-- .../contour_image.py | 14 ++++----- .../contour_label_demo.py | 4 +-- .../images_contours_and_fields/custom_cmap.py | 2 +- .../images_contours_and_fields/image_demo.py | 6 ++-- .../interpolation_methods.py | 2 +- .../images_contours_and_fields/quiver_demo.py | 13 ++++---- .../quiver_simple_demo.py | 5 ++-- .../line_demo_dash_control.py | 2 +- examples/misc/anchored_artists.py | 6 ++++ examples/recipes/fill_between_alpha.py | 2 +- examples/recipes/placing_text_boxes.py | 2 +- .../shapes_and_collections/ellipse_demo.py | 4 +-- .../subplots_axes_and_figures/subplot_demo.py | 2 +- .../custom_legends.py | 4 +-- lib/matplotlib/axes/_axes.py | 8 ++--- lib/matplotlib/figure.py | 2 +- lib/matplotlib/legend.py | 30 +++++++++---------- lib/matplotlib/legend_handler.py | 4 +-- lib/matplotlib/mathtext.py | 2 +- lib/matplotlib/ticker.py | 2 +- lib/matplotlib/widgets.py | 6 ++-- tutorials/advanced/transforms_tutorial.py | 2 +- tutorials/intermediate/tight_layout_guide.py | 2 +- tutorials/introductory/lifecycle.py | 15 +++++----- tutorials/introductory/pyplot.py | 16 +++++----- tutorials/introductory/sample_plots.py | 2 +- tutorials/introductory/usage.py | 10 +++---- tutorials/text/annotations.py | 4 +-- tutorials/text/mathtext.py | 8 ++--- tutorials/text/text_props.py | 8 ++--- tutorials/text/usetex.py | 18 +++++------ 55 files changed, 153 insertions(+), 151 deletions(-) diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index 4b83c9660788..dacb95c6660b 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -30,7 +30,7 @@ New dependency `kiwisolver `__ is now a required dependency to support the new constrained_layout, see -:ref:`sphx_glr_tutorials_intermediate_constrainedlayout_guide.py` for +:doc:`/tutorials/intermediate/constrainedlayout_guide` for more details. @@ -1603,7 +1603,7 @@ original location: * The legend handler interface has changed from a callable, to any object which implements the ``legend_artists`` method (a deprecation phase will see this interface be maintained for v1.4). See - :ref:`sphx_glr_tutorials_intermediate_legend_guide.py` for further details. Further legend changes + :doc:`/tutorials/intermediate/legend_guide` for further details. Further legend changes include: * :func:`matplotlib.axes.Axes._get_legend_handles` now returns a generator diff --git a/doc/api/pyplot_summary.rst b/doc/api/pyplot_summary.rst index db513d8c2660..4b290d5452af 100644 --- a/doc/api/pyplot_summary.rst +++ b/doc/api/pyplot_summary.rst @@ -8,7 +8,7 @@ The Pyplot API The :mod:`matplotlib.pyplot` module contains functions that allow you to generate many kinds of plots quickly. For examples that showcase the use of the :mod:`matplotlib.pyplot` module, see the -:ref:`sphx_glr_tutorials_introductory_pyplot.py` +:doc:`/tutorials/introductory/pyplot` or the :ref:`pyplots_examples`. We also recommend that you look into the object-oriented approach to plotting, described below. @@ -38,6 +38,6 @@ There are many colormaps you can use to map data onto color values. Below we list several ways in which color can be utilized in Matplotlib. For a more in-depth look at colormaps, see the -:ref:`sphx_glr_tutorials_colors_colormaps.py` tutorial. +:doc:`/tutorials/colors/colormaps` tutorial. .. autofunction:: colormaps diff --git a/doc/devel/contributing.rst b/doc/devel/contributing.rst index f04918ddbf16..35f376beea66 100644 --- a/doc/devel/contributing.rst +++ b/doc/devel/contributing.rst @@ -501,7 +501,7 @@ Developing a new backend ------------------------ If you are working on a custom backend, the *backend* setting in -:file:`matplotlibrc` (:ref:`sphx_glr_tutorials_introductory_customizing.py`) supports an +:file:`matplotlibrc` (:doc:`/tutorials/introductory/customizing`) supports an external backend via the ``module`` directive. If :file:`my_backend.py` is a Matplotlib backend in your :envvar:`PYTHONPATH`, you can set it on one of several ways diff --git a/doc/faq/howto_faq.rst b/doc/faq/howto_faq.rst index ab42bd303d10..0c4c27109248 100644 --- a/doc/faq/howto_faq.rst +++ b/doc/faq/howto_faq.rst @@ -43,7 +43,7 @@ If you only want to use the `pandas` converter for `datetime64` values :: Find all objects in a figure of a certain type ---------------------------------------------- -Every Matplotlib artist (see :ref:`sphx_glr_tutorials_intermediate_artists.py`) has a method +Every Matplotlib artist (see :doc:`/tutorials/intermediate/artists`) has a method called :meth:`~matplotlib.artist.Artist.findobj` that can be used to recursively search the artist for any artists it may contain that meet some criteria (e.g., match all :class:`~matplotlib.lines.Line2D` @@ -155,7 +155,7 @@ labels:: ax = fig.add_subplot(111) You can control the defaults for these parameters in your -:file:`matplotlibrc` file; see :ref:`sphx_glr_tutorials_introductory_customizing.py`. For +:file:`matplotlibrc` file; see :doc:`/tutorials/introductory/customizing`. For example, to make the above setting permanent, you would set:: figure.subplot.bottom : 0.2 # the bottom of the subplots of the figure @@ -186,7 +186,7 @@ specify the location explicitly:: ax = fig.add_axes([left, bottom, width, height]) where all values are in fractional (0 to 1) coordinates. See -:ref:`sphx_glr_gallery_subplots_axes_and_figures_axes_demo.py` for an example of placing axes manually. +:doc:`/gallery/subplots_axes_and_figures/axes_demo` for an example of placing axes manually. .. _howto-auto-adjust: @@ -196,7 +196,7 @@ Automatically make room for tick labels .. note:: This is now easier to handle than ever before. Calling :func:`~matplotlib.pyplot.tight_layout` can fix many common - layout issues. See the :ref:`sphx_glr_tutorials_intermediate_tight_layout_guide.py`. + layout issues. See the :doc:`/tutorials/intermediate/tight_layout_guide`. The information below is kept here in case it is useful for other purposes. @@ -348,7 +348,7 @@ and patches, respectively:: .. htmlonly:: - See :ref:`sphx_glr_gallery_misc_zorder_demo.py` for a complete example. + See :doc:`/gallery/misc/zorder_demo` for a complete example. You can also use the Axes property :meth:`~matplotlib.axes.Axes.set_axisbelow` to control whether the grid @@ -367,7 +367,7 @@ some ratio which controls the ratio:: .. htmlonly:: - See :ref:`sphx_glr_gallery_subplots_axes_and_figures_axis_equal_demo.py` for a + See :doc:`/gallery/subplots_axes_and_figures/axis_equal_demo` for a complete example. .. _howto-twoscale: @@ -411,7 +411,7 @@ locators as desired because the two axes are independent. .. htmlonly:: - See :ref:`sphx_glr_gallery_api_two_scales.py` for a complete example + See :doc:`/gallery/api/two_scales` for a complete example .. _howto-batch: @@ -657,7 +657,7 @@ For more on configuring your backend, see Alternatively, you can avoid pylab/pyplot altogether, which will give you a little more control, by calling the API directly as shown in -:ref:`sphx_glr_gallery_api_agg_oo_sgskip.py`. +:doc:`/gallery/api/agg_oo_sgskip`. You can either generate hardcopy on the filesystem by calling savefig:: diff --git a/doc/faq/installing_faq.rst b/doc/faq/installing_faq.rst index 8dcb047da395..67c4689f0ebf 100644 --- a/doc/faq/installing_faq.rst +++ b/doc/faq/installing_faq.rst @@ -26,7 +26,7 @@ example:: This will give you additional information about which backends matplotlib is loading, version information, and more. At this point you might want to make -sure you understand matplotlib's :ref:`configuration ` +sure you understand matplotlib's :doc:`configuration ` process, governed by the :file:`matplotlibrc` configuration file which contains instructions within and the concept of the matplotlib backend. diff --git a/doc/faq/troubleshooting_faq.rst b/doc/faq/troubleshooting_faq.rst index 3ceb9a578468..7002156948e2 100644 --- a/doc/faq/troubleshooting_faq.rst +++ b/doc/faq/troubleshooting_faq.rst @@ -104,7 +104,7 @@ provide the following information in your e-mail to the `mailing list `Enthought Canopy `_). * Any customizations to your ``matplotlibrc`` file (see - :ref:`sphx_glr_tutorials_introductory_customizing.py`). + :doc:`/tutorials/introductory/customizing`). * If the problem is reproducible, please try to provide a *minimal*, standalone Python script that demonstrates the problem. This is *the* critical step. diff --git a/doc/mpl_toolkits/index.rst b/doc/mpl_toolkits/index.rst index 285f9d49295a..b4322f578def 100644 --- a/doc/mpl_toolkits/index.rst +++ b/doc/mpl_toolkits/index.rst @@ -21,7 +21,7 @@ mplot3d plotting (scatter, surf, line, mesh) tools. Not the fastest or most feature complete 3D library out there, but it ships with Matplotlib and thus may be a lighter weight solution for some use cases. Check out the -:ref:`mplot3d tutorial ` for more +:doc:`mplot3d tutorial ` for more information. .. figure:: ../gallery/mplot3d/images/sphx_glr_contourf3d_2_001.png diff --git a/doc/mpl_toolkits/mplot3d/index.rst b/doc/mpl_toolkits/mplot3d/index.rst index 22d2368912e9..b53d0fc153c9 100644 --- a/doc/mpl_toolkits/mplot3d/index.rst +++ b/doc/mpl_toolkits/mplot3d/index.rst @@ -11,7 +11,7 @@ The mplot3d toolkit adds simple 3D plotting capabilities to matplotlib by supplying an axes object that can create a 2D projection of a 3D scene. The resulting graph will have the same look and feel as regular 2D plots. -See the :ref:`mplot3d tutorial ` for +See the :doc:`mplot3d tutorial ` for more information on how to use this toolkit. .. image:: ../../_static/demo_mplot3d.png diff --git a/doc/users/dflt_style_changes.rst b/doc/users/dflt_style_changes.rst index f2a7badf6f2c..22624683892b 100644 --- a/doc/users/dflt_style_changes.rst +++ b/doc/users/dflt_style_changes.rst @@ -96,7 +96,7 @@ are only specified via hex values. To access these colors outside of the property cycling the notation for colors ``'CN'``, where ``N`` takes values 0-9, was added to denote the first 10 colors in ``mpl.rcParams['axes.prop_cycle']`` See -:ref:`sphx_glr_tutorials_colors_colors.py` for more details. +:doc:`/tutorials/colors/colors` for more details. To restore the old color cycle use @@ -145,7 +145,7 @@ watch Nathaniel Smith and Stéfan van der Walt's talk from SciPy2015. See `here for many more details `__ about the other alternatives and the tools used to create the color map. For details on all of the color maps available in matplotlib see -:ref:`sphx_glr_tutorials_colors_colormaps.py`. +:doc:`/tutorials/colors/colormaps`. .. raw:: html diff --git a/doc/users/prev_whats_new/whats_new_0.98.4.rst b/doc/users/prev_whats_new/whats_new_0.98.4.rst index c10f15743f0e..a7339d6027f6 100644 --- a/doc/users/prev_whats_new/whats_new_0.98.4.rst +++ b/doc/users/prev_whats_new/whats_new_0.98.4.rst @@ -79,7 +79,7 @@ psd amplitude scaling Ryan May did a lot of work to rationalize the amplitude scaling of :func:`~matplotlib.pyplot.psd` and friends. See -:ref:`sphx_glr_gallery_lines_bars_and_markers_psd_demo.py`. +:doc:`/gallery/lines_bars_and_markers/psd_demo`. The changes should increase MATLAB compatibility and increase scaling options. diff --git a/doc/users/prev_whats_new/whats_new_0.99.rst b/doc/users/prev_whats_new/whats_new_0.99.rst index 8ae2055a751e..2ffebe153eb6 100644 --- a/doc/users/prev_whats_new/whats_new_0.99.rst +++ b/doc/users/prev_whats_new/whats_new_0.99.rst @@ -11,11 +11,11 @@ New in matplotlib 0.99 New documentation ----------------- -Jae-Joon Lee has written two new guides :ref:`sphx_glr_tutorials_intermediate_legend_guide.py` +Jae-Joon Lee has written two new guides :doc:`/tutorials/intermediate/legend_guide` and :ref:`plotting-guide-annotation`. Michael Sarahan has written -:ref:`sphx_glr_tutorials_introductory_images.py`. John Hunter has written two new tutorials on -working with paths and transformations: :ref:`sphx_glr_tutorials_advanced_path_tutorial.py` and -:ref:`sphx_glr_tutorials_advanced_transforms_tutorial.py`. +:doc:`/tutorials/introductory/images`. John Hunter has written two new tutorials on +working with paths and transformations: :doc:`/tutorials/advanced/path_tutorial` and +:doc:`/tutorials/advanced/transforms_tutorial`. .. _whats-new-mplot3d: @@ -65,7 +65,7 @@ that denote the data limits -- in various arbitrary locations. No longer are your axis lines constrained to be a simple rectangle around the figure -- you can turn on or off left, bottom, right and top, as well as "detach" the spine to offset it away from the data. See -:ref:`sphx_glr_gallery_ticks_and_spines_spine_placement_demo.py` and +:doc:`/gallery/ticks_and_spines/spine_placement_demo` and :class:`matplotlib.spines.Spine`. .. figure:: ../../gallery/pyplots/images/sphx_glr_whats_new_99_spines_001.png diff --git a/doc/users/prev_whats_new/whats_new_1.0.rst b/doc/users/prev_whats_new/whats_new_1.0.rst index 3675c528aa7d..5d7403c91b1b 100644 --- a/doc/users/prev_whats_new/whats_new_1.0.rst +++ b/doc/users/prev_whats_new/whats_new_1.0.rst @@ -23,7 +23,7 @@ Sophisticated subplot grid layout Jae-Joon Lee has written :mod:`~matplotlib.gridspec`, a new module for doing complex subplot layouts, featuring row and column spans and -more. See :ref:`sphx_glr_tutorials_intermediate_gridspec.py` for a tutorial overview. +more. See :doc:`/tutorials/intermediate/gridspec` for a tutorial overview. .. figure:: ../../gallery/userdemo/images/sphx_glr_demo_gridspec01_000.png :target: ../../gallery/userdemo/demo_gridspec01.html @@ -44,7 +44,7 @@ indexing (starts with 0). e.g.:: fig, axarr = plt.subplots(2, 2) axarr[0,0].plot([1,2,3]) # upper, left -See :ref:`sphx_glr_gallery_subplots_axes_and_figures_subplot_demo.py` for several code examples. +See :doc:`/gallery/subplots_axes_and_figures/subplot_demo` for several code examples. Contour fixes and and triplot --------------------------------- diff --git a/doc/users/prev_whats_new/whats_new_1.1.rst b/doc/users/prev_whats_new/whats_new_1.1.rst index 80c0aaea240b..cf9d38dd234a 100644 --- a/doc/users/prev_whats_new/whats_new_1.1.rst +++ b/doc/users/prev_whats_new/whats_new_1.1.rst @@ -17,8 +17,8 @@ Sankey Diagrams Kevin Davies has extended Yannick Copin's original Sankey example into a module (:mod:`~matplotlib.sankey`) and provided new examples -(:ref:`sphx_glr_gallery_api_sankey_basics.py`, :ref:`sphx_glr_gallery_api_sankey_links.py`, -:ref:`sphx_glr_gallery_api_sankey_rankine.py`). +(:doc:`/gallery/api/sankey_basics`, :doc:`/gallery/api/sankey_links`, +:doc:`/gallery/api/sankey_rankine`). .. figure:: ../../gallery/api/images/sphx_glr_sankey_rankine_001.png :target: ../../gallery/api/sankey_rankine.html @@ -87,7 +87,7 @@ The usage of this functionality can be as simple as :: and it will adjust the spacing between subplots so that the axis labels do not overlap with neighboring subplots. A -:ref:`sphx_glr_tutorials_intermediate_tight_layout_guide.py` has been created to show how to use +:doc:`/tutorials/intermediate/tight_layout_guide` has been created to show how to use this new tool. PyQT4, PySide, and IPython @@ -116,7 +116,7 @@ legends for complex plots such as :meth:`~matplotlib.pyplot.stem` plots will now display correctly. Second, the 'best' placement of a legend has been improved in the presence of NANs. -See the :ref:`sphx_glr_tutorials_intermediate_legend_guide.py` for more detailed explanation and +See the :doc:`/tutorials/intermediate/legend_guide` for more detailed explanation and examples. .. figure:: ../../gallery/text_labels_and_annotations/images/sphx_glr_legend_demo_004.png diff --git a/doc/users/prev_whats_new/whats_new_1.2.rst b/doc/users/prev_whats_new/whats_new_1.2.rst index 495d674a3e00..01104c1b55a1 100644 --- a/doc/users/prev_whats_new/whats_new_1.2.rst +++ b/doc/users/prev_whats_new/whats_new_1.2.rst @@ -39,7 +39,7 @@ PGF/TikZ backend Peter Würtz wrote a backend that allows matplotlib to export figures as drawing commands for LaTeX. These can be processed by PdfLaTeX, XeLaTeX or LuaLaTeX using the PGF/TikZ package. Usage examples and documentation are -found in :ref:`sphx_glr_tutorials_text_pgf.py`. +found in :doc:`/tutorials/text/pgf`. .. image:: /_static/pgf_preamble.* diff --git a/doc/users/prev_whats_new/whats_new_1.4.rst b/doc/users/prev_whats_new/whats_new_1.4.rst index ffbd1701754b..48dbd8266e22 100644 --- a/doc/users/prev_whats_new/whats_new_1.4.rst +++ b/doc/users/prev_whats_new/whats_new_1.4.rst @@ -82,8 +82,8 @@ with :func:`~matplotlib.Axes.bxp`. Lastly, each artist (e.g., the box, outliers, cap, notches) can now be toggled on or off and their styles can be passed in through individual kwargs. See the examples: -:ref:`sphx_glr_gallery_statistics_boxplot.py` and -:ref:`sphx_glr_gallery_statistics_bxp.py` +:doc:`/gallery/statistics/boxplot` and +:doc:`/gallery/statistics/bxp` Added a bool kwarg, :code:`manage_xticks`, which if False disables the management of the ticks and limits on the x-axis by :func:`~matplotlib.axes.Axes.bxp`. @@ -410,7 +410,7 @@ instead of ``:context:`` any time you want to reset the context. Legend and PathEffects documentation ------------------------------------ -The :ref:`sphx_glr_tutorials_intermediate_legend_guide.py` and :ref:`sphx_glr_tutorials_advanced_patheffects_guide.py` have both been +The :doc:`/tutorials/intermediate/legend_guide` and :doc:`/tutorials/advanced/patheffects_guide` have both been updated to better reflect the full potential of each of these powerful features. diff --git a/doc/users/prev_whats_new/whats_new_1.5.rst b/doc/users/prev_whats_new/whats_new_1.5.rst index 19610709498f..854cb889f746 100644 --- a/doc/users/prev_whats_new/whats_new_1.5.rst +++ b/doc/users/prev_whats_new/whats_new_1.5.rst @@ -679,7 +679,7 @@ mutually exclusive inside that group. For tools derived from that are called automatically whenever it is toggled. -A full example is located in :ref:`sphx_glr_gallery_user_interfaces_toolmanager_sgskip.py` +A full example is located in :doc:`/gallery/user_interfaces/toolmanager_sgskip` cbook.is_sequence_of_strings recognizes string objects diff --git a/doc/users/prev_whats_new/whats_new_2.0.0.rst b/doc/users/prev_whats_new/whats_new_2.0.0.rst index 809b3ac4da25..b16a3d97dc3d 100644 --- a/doc/users/prev_whats_new/whats_new_2.0.0.rst +++ b/doc/users/prev_whats_new/whats_new_2.0.0.rst @@ -275,7 +275,7 @@ Filled ``+`` and ``x`` markers New fillable *plus* and *x* markers have been added. See the :mod:`~matplotlib.markers` module and -:ref:`marker reference ` +:doc:`marker reference ` examples. `rcount` and `ccount` for `plot_surface()` diff --git a/doc/users/prev_whats_new/whats_new_2.1.0.rst b/doc/users/prev_whats_new/whats_new_2.1.0.rst index 171dc7291a9f..86b416ae1284 100644 --- a/doc/users/prev_whats_new/whats_new_2.1.0.rst +++ b/doc/users/prev_whats_new/whats_new_2.1.0.rst @@ -139,7 +139,7 @@ PolygonSelector A :class:`~matplotlib.widgets.PolygonSelector` class has been added to :mod:`matplotlib.widgets`. See -:ref:`sphx_glr_gallery_widgets_polygon_selector_demo.py` for details. +:doc:`/gallery/widgets/polygon_selector_demo` for details. Added `matplotlib.ticker.PercentFormatter` diff --git a/doc/users/shell.rst b/doc/users/shell.rst index 99625f1957c7..c9e659fdf249 100644 --- a/doc/users/shell.rst +++ b/doc/users/shell.rst @@ -92,7 +92,7 @@ are going to need to understand what a matplotlib backend is With the TkAgg backend, which uses the Tkinter user interface toolkit, you can use matplotlib from an arbitrary non-gui python shell. Just set your ``backend : TkAgg`` and ``interactive : True`` in your -:file:`matplotlibrc` file (see :ref:`sphx_glr_tutorials_introductory_customizing.py`) and fire +:file:`matplotlibrc` file (see :doc:`/tutorials/introductory/customizing`) and fire up python. Then:: >>> from pylab import * diff --git a/examples/axes_grid1/simple_anchored_artists.py b/examples/axes_grid1/simple_anchored_artists.py index 3d0527298a4c..bbfd245122d8 100644 --- a/examples/axes_grid1/simple_anchored_artists.py +++ b/examples/axes_grid1/simple_anchored_artists.py @@ -3,6 +3,10 @@ Simple Anchored Artists ======================= +This example illustrates the use of the anchored helper classes found in +:py:mod:`~matplotlib.offsetbox` and in the :ref:`toolkit_axesgrid1-index`. +An implementation of a similar figure, but without use of the toolkit, +can be found in :doc:`/gallery/misc/anchored_artists`. """ import matplotlib.pyplot as plt diff --git a/examples/color/color_cycle_default.py b/examples/color/color_cycle_default.py index d4f70a0d90df..8de0048b54a9 100644 --- a/examples/color/color_cycle_default.py +++ b/examples/color/color_cycle_default.py @@ -4,7 +4,7 @@ ==================================== Display the colors from the default prop_cycle, which is obtained from the -:ref:`rc parameters`. +:doc:`rc parameters`. """ import numpy as np import matplotlib.pyplot as plt diff --git a/examples/color/color_demo.py b/examples/color/color_demo.py index 9740744f3cfe..d366f0a1b959 100644 --- a/examples/color/color_demo.py +++ b/examples/color/color_demo.py @@ -26,9 +26,9 @@ For more information on colors in matplotlib see -* the :ref:`sphx_glr_tutorials_colors_colors.py` tutorial; +* the :doc:`/tutorials/colors/colors` tutorial; * the `matplotlib.colors` API; -* the :ref:`sphx_glr_gallery_color_named_colors.py` example. +* the :doc:`/gallery/color/named_colors` example. """ import matplotlib.pyplot as plt diff --git a/examples/color/named_colors.py b/examples/color/named_colors.py index facaee7bb5f4..062dd4c54fff 100644 --- a/examples/color/named_colors.py +++ b/examples/color/named_colors.py @@ -7,9 +7,9 @@ For more information on colors in matplotlib see -* the :ref:`sphx_glr_tutorials_colors_colors.py` tutorial; +* the :doc:`/tutorials/colors/colors` tutorial; * the `matplotlib.colors` API; -* the :ref:`sphx_glr_gallery_color_color_demo.py`. +* the :doc:`/gallery/color/color_demo`. """ from __future__ import division diff --git a/examples/images_contours_and_fields/contour_demo.py b/examples/images_contours_and_fields/contour_demo.py index 5fe006134051..9cdc568597bb 100644 --- a/examples/images_contours_and_fields/contour_demo.py +++ b/examples/images_contours_and_fields/contour_demo.py @@ -6,9 +6,8 @@ Illustrate simple contour plotting, contours on an image with a colorbar for the contours, and labelled contours. -See also the -:ref:`contour image example -`. +See also the :doc:`contour image example +`. """ import matplotlib import numpy as np diff --git a/examples/images_contours_and_fields/contour_image.py b/examples/images_contours_and_fields/contour_image.py index d1e088bc5f25..df2cc7c381f1 100644 --- a/examples/images_contours_and_fields/contour_image.py +++ b/examples/images_contours_and_fields/contour_image.py @@ -4,16 +4,14 @@ ============= Test combinations of contouring, filled contouring, and image plotting. -For contour labelling, see See also the -:ref:`contour demo example -`. +For contour labelling, see also the :doc:`contour demo example +`. The emphasis in this demo is on showing how to make contours register -correctly on images, and on how to get both of them oriented as -desired. In particular, note the usage of the -:ref:`"origin" and "extent" -` -keyword arguments to imshow and contour. +correctly on images, and on how to get both of them oriented as desired. +In particular, note the usage of the :doc:`"origin" and "extent" +` keyword arguments to imshow and +contour. """ import matplotlib.pyplot as plt import numpy as np diff --git a/examples/images_contours_and_fields/contour_label_demo.py b/examples/images_contours_and_fields/contour_label_demo.py index b3c2c75cb801..af26ab997c87 100644 --- a/examples/images_contours_and_fields/contour_label_demo.py +++ b/examples/images_contours_and_fields/contour_label_demo.py @@ -6,8 +6,8 @@ Illustrate some of the more advanced things that one can do with contour labels. -See also the :ref:`contour demo example -`. +See also the :doc:`contour demo example +`. """ import matplotlib diff --git a/examples/images_contours_and_fields/custom_cmap.py b/examples/images_contours_and_fields/custom_cmap.py index 5334576ec044..153176ccb1ae 100644 --- a/examples/images_contours_and_fields/custom_cmap.py +++ b/examples/images_contours_and_fields/custom_cmap.py @@ -3,7 +3,7 @@ Creating a colormap from a list of colors ========================================= -Creating a :ref:`colormap ` +Creating a :doc:`colormap ` from a list of colors can be done with the :meth:`~.colors.LinearSegmentedColormap.from_list` method of `LinearSegmentedColormap`. You must pass a list of RGB tuples that define the diff --git a/examples/images_contours_and_fields/image_demo.py b/examples/images_contours_and_fields/image_demo.py index 4e8e14033b6e..123bfc2c9d5c 100644 --- a/examples/images_contours_and_fields/image_demo.py +++ b/examples/images_contours_and_fields/image_demo.py @@ -115,7 +115,7 @@ # This allows you to plot the full range of your array w/o edge effects, # and for example to layer multiple images of different sizes over one # another with different interpolation methods - see -# :ref:`sphx_glr_gallery_images_contours_and_fields_layer_images.py`. +# :doc:`/gallery/images_contours_and_fields/layer_images`. # It also implies a performance hit, as this # new temporary, padded array must be created. Sophisticated # interpolation also implies a performance hit, so if you need maximal @@ -138,8 +138,8 @@ # x[0,0] in the upper left or lower right by using the origin parameter. # You can also control the default setting image.origin in your # :ref:`matplotlibrc file `. For more on -# this topic see the :ref:`complete guide on origin and extent -# `. +# this topic see the :doc:`complete guide on origin and extent +# `. x = np.arange(120).reshape((10, 12)) diff --git a/examples/images_contours_and_fields/interpolation_methods.py b/examples/images_contours_and_fields/interpolation_methods.py index 3e90986237b6..08efa9f5d5df 100644 --- a/examples/images_contours_and_fields/interpolation_methods.py +++ b/examples/images_contours_and_fields/interpolation_methods.py @@ -7,7 +7,7 @@ :meth:`~.axes.Axes.imshow` and :meth:`~.axes.Axes.matshow`. If `interpolation` is None, it defaults to the ``image.interpolation`` -:ref:`rc parameter `. +:doc:`rc parameter `. If the interpolation is ``'none'``, then no interpolation is performed for the Agg, ps and pdf backends. Other backends will default to ``'nearest'``. diff --git a/examples/images_contours_and_fields/quiver_demo.py b/examples/images_contours_and_fields/quiver_demo.py index 4d0cfb0450d9..7c1711710076 100644 --- a/examples/images_contours_and_fields/quiver_demo.py +++ b/examples/images_contours_and_fields/quiver_demo.py @@ -3,14 +3,13 @@ Demonstration of advanced quiver and quiverkey functions ======================================================== -Demonstrates some more advanced options for `~.axes.Axes.quiver`. -For a simple example refer to -:ref:`sphx_glr_gallery_images_contours_and_fields_quiver_simple_demo.py`. +Demonstrates some more advanced options for `~.axes.Axes.quiver`. For a simple +example refer to :doc:`/gallery/images_contours_and_fields/quiver_simple_demo`. -Known problem: the plot autoscaling does not take into account -the arrows, so those on the boundaries are often out of the picture. -This is *not* an easy problem to solve in a perfectly general way. -The workaround is to manually expand the Axes objects. +Known problem: the plot autoscaling does not take into account the arrows, so +those on the boundaries are often out of the picture. This is *not* an easy +problem to solve in a perfectly general way. The workaround is to manually +expand the Axes objects. """ import matplotlib.pyplot as plt import numpy as np diff --git a/examples/images_contours_and_fields/quiver_simple_demo.py b/examples/images_contours_and_fields/quiver_simple_demo.py index 9c7e3644de1a..0393a4857cbd 100644 --- a/examples/images_contours_and_fields/quiver_simple_demo.py +++ b/examples/images_contours_and_fields/quiver_simple_demo.py @@ -3,11 +3,10 @@ Quiver Simple Demo ================== -A simple example of a `~.axes.Axes.quiver` plot with a -`~.axes.Axes.quiverkey`. +A simple example of a `~.axes.Axes.quiver` plot with a `~.axes.Axes.quiverkey`. For more advanced options refer to -:ref:`sphx_glr_gallery_images_contours_and_fields_quiver_demo.py`. +:doc:`/gallery/images_contours_and_fields/quiver_demo`. """ import matplotlib.pyplot as plt import numpy as np diff --git a/examples/lines_bars_and_markers/line_demo_dash_control.py b/examples/lines_bars_and_markers/line_demo_dash_control.py index af4411daf0c9..78043dfed2ff 100644 --- a/examples/lines_bars_and_markers/line_demo_dash_control.py +++ b/examples/lines_bars_and_markers/line_demo_dash_control.py @@ -14,7 +14,7 @@ line. *Note*: The dash style can also be configured via a -:ref:`property_cycle ` +:doc:`property_cycle ` by passing a list of dash sequences using the keyword *dashes* to the cycler. This is not shown within this example. """ diff --git a/examples/misc/anchored_artists.py b/examples/misc/anchored_artists.py index 94f6be340369..3f7ad99c3030 100644 --- a/examples/misc/anchored_artists.py +++ b/examples/misc/anchored_artists.py @@ -3,6 +3,12 @@ Anchored Artists ================ +This example illustrates the use of the anchored objects without the +helper classes found in the :ref:`toolkit_axesgrid1-index`. This version +of the figure is similar to the one found in +:doc:`/gallery/axes_grid1/simple_anchored_artists`, but it is +implemented using only the matplotlib namespace, without the help +of additional toolkits. """ from matplotlib.patches import Rectangle, Ellipse diff --git a/examples/recipes/fill_between_alpha.py b/examples/recipes/fill_between_alpha.py index eb7d503ee54a..dc0eaaf9326d 100644 --- a/examples/recipes/fill_between_alpha.py +++ b/examples/recipes/fill_between_alpha.py @@ -133,6 +133,6 @@ # vertical spans of an axes -- for that matplotlib has some helper # functions :meth:`~matplotlib.axes.Axes.axhspan` and # :meth:`~matplotlib.axes.Axes.axvspan` and example -# :ref:`sphx_glr_gallery_subplots_axes_and_figures_axhspan_demo.py`. +# :doc:`/gallery/subplots_axes_and_figures/axhspan_demo`. plt.show() diff --git a/examples/recipes/placing_text_boxes.py b/examples/recipes/placing_text_boxes.py index 7ec033df6e1a..ef64337f0075 100644 --- a/examples/recipes/placing_text_boxes.py +++ b/examples/recipes/placing_text_boxes.py @@ -3,7 +3,7 @@ ================== When decorating axes with text boxes, two useful tricks are to place -the text in axes coordinates (see :ref:`sphx_glr_tutorials_advanced_transforms_tutorial.py`), so the +the text in axes coordinates (see :doc:`/tutorials/advanced/transforms_tutorial`), so the text doesn't move around with changes in x or y limits. You can also use the ``bbox`` property of text to surround the text with a :class:`~matplotlib.patches.Patch` instance -- the ``bbox`` keyword diff --git a/examples/shapes_and_collections/ellipse_demo.py b/examples/shapes_and_collections/ellipse_demo.py index 21fbe7d9c0e5..29d8c2694b8b 100644 --- a/examples/shapes_and_collections/ellipse_demo.py +++ b/examples/shapes_and_collections/ellipse_demo.py @@ -4,8 +4,8 @@ ============ Draw many ellipses. Here individual ellipses are drawn. Compare this -to the :ref:`Ellipse collection example -`. +to the :doc:`Ellipse collection example +`. """ import matplotlib.pyplot as plt import numpy as np diff --git a/examples/subplots_axes_and_figures/subplot_demo.py b/examples/subplots_axes_and_figures/subplot_demo.py index 828184dde624..836476829a65 100644 --- a/examples/subplots_axes_and_figures/subplot_demo.py +++ b/examples/subplots_axes_and_figures/subplot_demo.py @@ -5,7 +5,7 @@ Demo with two subplots. For more options, see -:ref:`sphx_glr_gallery_subplots_axes_and_figures_subplots_demo.py` +:doc:`/gallery/subplots_axes_and_figures/subplots_demo` """ import numpy as np import matplotlib.pyplot as plt diff --git a/examples/text_labels_and_annotations/custom_legends.py b/examples/text_labels_and_annotations/custom_legends.py index 81e3795ddab9..f37cd2ab61fd 100644 --- a/examples/text_labels_and_annotations/custom_legends.py +++ b/examples/text_labels_and_annotations/custom_legends.py @@ -10,8 +10,8 @@ For more information on creating and customizing legends, see the following pages: - * :ref:`sphx_glr_tutorials_intermediate_legend_guide.py` - * :ref:`sphx_glr_gallery_text_labels_and_annotations_legend_demo.py` + * :doc:`/tutorials/intermediate/legend_guide` + * :doc:`/gallery/text_labels_and_annotations/legend_demo` Sometimes you don't want a legend that is explicitly tied to data that you have plotted. For example, say you have plotted 10 lines, but don't diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index e2c293114ca6..210d02e58ccf 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -540,7 +540,7 @@ def legend(self, *args, **kwargs): ----- Not all kinds of artist are supported by the legend command. See - :ref:`sphx_glr_tutorials_intermediate_legend_guide.py` for details. + :doc:`/tutorials/intermediate/legend_guide` for details. Examples -------- @@ -2094,7 +2094,7 @@ def bar(self, *args, **kwargs): upper errors. - *None*: No errorbar. (Default) - See :ref:`sphx_glr_gallery_statistics_errorbar_features.py` + See :doc:`/gallery/statistics/errorbar_features` for an example on the usage of ``xerr`` and ``yerr``. ecolor : scalar or array-like, optional, default: 'black' @@ -2418,7 +2418,7 @@ def barh(self, *args, **kwargs): upper errors. - *None*: No errorbar. (default) - See :ref:`sphx_glr_gallery_statistics_errorbar_features.py` + See :doc:`/gallery/statistics/errorbar_features` for an example on the usage of ``xerr`` and ``yerr``. ecolor : scalar or array-like, optional, default: 'black' @@ -3006,7 +3006,7 @@ def errorbar(self, x, y, yerr=None, xerr=None, upper errors. - *None*: No errorbar. - See :ref:`sphx_glr_gallery_statistics_errorbar_features.py` + See :doc:`/gallery/statistics/errorbar_features` for an example on the usage of ``xerr`` and ``yerr``. fmt : plot format string, optional, default: '' diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index dd24a060d666..fb734a2fdd21 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1715,7 +1715,7 @@ def legend(self, *args, **kwargs): Notes ----- Not all kinds of artist are supported by the legend command. See - :ref:`sphx_glr_tutorials_intermediate_legend_guide.py` for details. + :doc:`/tutorials/intermediate/legend_guide` for details. """ handles, labels, extra_args, kwargs = mlegend._parse_legend_args( diff --git a/lib/matplotlib/legend.py b/lib/matplotlib/legend.py index ca0bf1f238ca..c2affe93ef01 100644 --- a/lib/matplotlib/legend.py +++ b/lib/matplotlib/legend.py @@ -4,23 +4,21 @@ .. important:: - It is unlikely that you would ever create a Legend instance manually. - Most users would normally create a legend via the + It is unlikely that you would ever create a Legend instance + manually. Most users would normally create a legend via the :meth:`~matplotlib.axes.Axes.legend` function. For more details on legends - there is also a :ref:`legend guide - `. - -The Legend class can be considered as a container of legend handles -and legend texts. Creation of corresponding legend handles from the -plot elements in the axes or figures (e.g., lines, patches, etc.) are -specified by the handler map, which defines the mapping between the -plot elements and the legend handlers to be used (the default legend -handlers are defined in the :mod:`~matplotlib.legend_handler` module). -Note that not all kinds of artist are supported by the legend yet by default -but it is possible to extend the legend handler's capabilities to support -arbitrary objects. See the :ref:`legend guide -` for more information. - + there is also a :doc:`legend guide `. + +The Legend class can be considered as a container of legend handles and +legend texts. Creation of corresponding legend handles from the plot elements +in the axes or figures (e.g., lines, patches, etc.) are specified by the +handler map, which defines the mapping between the plot elements and the +legend handlers to be used (the default legend handlers are defined in the +:mod:`~matplotlib.legend_handler` module). Note that not all kinds of +artist are supported by the legend yet by default but it is possible to +extend the legend handler's capabilities to support arbitrary objects. See +the :doc:`legend guide ` for more +information. """ from __future__ import (absolute_import, division, print_function, unicode_literals) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index 0968a5c4b99b..e1a7e2d03d11 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -1,8 +1,8 @@ """ This module defines default legend handlers. -It is strongly encouraged to have read the :ref:`legend guide -` before this documentation. +It is strongly encouraged to have read the :doc:`legend guide +` before this documentation. Legend handlers are expected to be a callable object with a following signature. :: diff --git a/lib/matplotlib/mathtext.py b/lib/matplotlib/mathtext.py index 4a8a27e98ea4..dee778b0d0aa 100644 --- a/lib/matplotlib/mathtext.py +++ b/lib/matplotlib/mathtext.py @@ -2,7 +2,7 @@ :mod:`~matplotlib.mathtext` is a module for parsing a subset of the TeX math syntax and drawing them to a matplotlib backend. -For a tutorial of its usage see :ref:`sphx_glr_tutorials_text_mathtext.py`. This +For a tutorial of its usage see :doc:`/tutorials/text/mathtext`. This document is primarily concerned with implementation details. The module uses pyparsing_ to parse the TeX expression. diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 1c07c85942e9..cd007bb993fc 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -159,7 +159,7 @@ ax.yaxis.set_major_formatter(ymajor_formatter) ax.yaxis.set_minor_formatter(yminor_formatter) -See :ref:`sphx_glr_gallery_ticks_and_spines_major_minor_demo.py` for an +See :doc:`/gallery/ticks_and_spines/major_minor_demo` for an example of setting major and minor ticks. See the :mod:`matplotlib.dates` module for more information and examples of using date locators and formatters. """ diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py index ac6198ff8587..0563964da69d 100644 --- a/lib/matplotlib/widgets.py +++ b/lib/matplotlib/widgets.py @@ -1734,7 +1734,7 @@ class SpanSelector(_SelectorWidget): rectprops=rectprops) >>> fig.show() - See also: :ref:`sphx_glr_gallery_widgets_span_selector.py` + See also: :doc:`/gallery/widgets/span_selector` """ @@ -2572,9 +2572,9 @@ class PolygonSelector(_SelectorWidget): if the mouse click is within `vertex_select_radius` pixels of the vertex. The default radius is 15 pixels. - See Also + Examples -------- - :ref:`sphx_glr_gallery_widgets_polygon_selector_demo.py` + :doc:`/gallery/widgets/polygon_selector_demo` """ def __init__(self, ax, onselect, useblit=False, diff --git a/tutorials/advanced/transforms_tutorial.py b/tutorials/advanced/transforms_tutorial.py index 7fd477e2bd06..b0f39b7eae92 100644 --- a/tutorials/advanced/transforms_tutorial.py +++ b/tutorials/advanced/transforms_tutorial.py @@ -467,4 +467,4 @@ # see how to make your own, since Matplotlib supports extensible axes # and projections. Michael Droettboom has provided a nice tutorial # example of creating a Hammer projection axes; see -# :ref:`sphx_glr_gallery_misc_custom_projection.py`. +# :doc:`/gallery/misc/custom_projection`. diff --git a/tutorials/intermediate/tight_layout_guide.py b/tutorials/intermediate/tight_layout_guide.py index 6318032e6412..04d7a045fc2f 100644 --- a/tutorials/intermediate/tight_layout_guide.py +++ b/tutorials/intermediate/tight_layout_guide.py @@ -115,7 +115,7 @@ def example_plot(ax, fontsize=12): ############################################################################### # It works with subplots created with # :func:`~matplotlib.pyplot.subplot2grid`. In general, subplots created -# from the gridspec (:ref:`sphx_glr_tutorials_intermediate_gridspec.py`) will work. +# from the gridspec (:doc:`/tutorials/intermediate/gridspec`) will work. plt.close('all') fig = plt.figure() diff --git a/tutorials/introductory/lifecycle.py b/tutorials/introductory/lifecycle.py index 68770cf9efe0..c8af6d5c6183 100644 --- a/tutorials/introductory/lifecycle.py +++ b/tutorials/introductory/lifecycle.py @@ -23,11 +23,10 @@ interface. In this case, we utilize an instance of :class:`axes.Axes` in order to render visualizations on an instance of :class:`figure.Figure`. -The second is based on MATLAB and uses -a state-based interface. This is encapsulated in the :mod:`pyplot` -module. See the :ref:`pyplot tutorials -` -for a more in-depth look at the pyplot interface. +The second is based on MATLAB and uses a state-based interface. This is +encapsulated in the :mod:`pyplot` module. See the :doc:`pyplot tutorials +` for a more in-depth look at the pyplot +interface. Most of the terms are straightforward but the main thing to remember is that: @@ -85,8 +84,8 @@ # .. note:: # # Figures can have multiple axes on them. For information on how to do this, -# see the :ref:`Tight Layout tutorial -# `. +# see the :doc:`Tight Layout tutorial +# `. fig, ax = plt.subplots() @@ -149,7 +148,7 @@ # that we create. To do this we'll set the ``autolayout`` value of our # rcParams. For more information on controlling the style, layout, and # other features of plots with rcParams, see -# :ref:`sphx_glr_tutorials_introductory_customizing.py`. +# :doc:`/tutorials/introductory/customizing`. plt.rcParams.update({'figure.autolayout': True}) diff --git a/tutorials/introductory/pyplot.py b/tutorials/introductory/pyplot.py index 92fc3a3dfdf6..b21aea8b14c3 100644 --- a/tutorials/introductory/pyplot.py +++ b/tutorials/introductory/pyplot.py @@ -277,8 +277,8 @@ def f(t): # rectangular grid, use the :func:`~matplotlib.pyplot.axes` command, # which allows you to specify the location as ``axes([left, bottom, # width, height])`` where all values are in fractional (0 to 1) -# coordinates. See :ref:`sphx_glr_gallery_subplots_axes_and_figures_axes_demo.py` for an example of -# placing axes manually and :ref:`sphx_glr_gallery_subplots_axes_and_figures_subplot_demo.py` for an +# coordinates. See :doc:`/gallery/subplots_axes_and_figures/axes_demo` for an example of +# placing axes manually and :doc:`/gallery/subplots_axes_and_figures/subplot_demo` for an # example with lots of subplots. # # @@ -307,7 +307,7 @@ def f(t): # it annoying that states (specifically the current image, figure and axes) # are being maintained for you behind the scenes, don't despair: this is just a thin # stateful wrapper around an object oriented API, which you can use -# instead (see :ref:`sphx_glr_tutorials_intermediate_artists.py`) +# instead (see :doc:`/tutorials/intermediate/artists`) # # If you are making lots of figures, you need to be aware of one # more thing: the memory required for a figure is not completely @@ -326,7 +326,7 @@ def f(t): # The :func:`~matplotlib.pyplot.text` command can be used to add text in # an arbitrary location, and the :func:`~matplotlib.pyplot.xlabel`, # :func:`~matplotlib.pyplot.ylabel` and :func:`~matplotlib.pyplot.title` -# are used to add text in the indicated locations (see :ref:`sphx_glr_tutorials_text_text_intro.py` +# are used to add text in the indicated locations (see :doc:`/tutorials/text/text_intro` # for a more detailed example) mu, sigma = 100, 15 @@ -352,7 +352,7 @@ def f(t): # # t = plt.xlabel('my data', fontsize=14, color='red') # -# These properties are covered in more detail in :ref:`sphx_glr_tutorials_text_text_props.py`. +# These properties are covered in more detail in :doc:`/tutorials/text/text_props`. # # # Using mathematical expressions in text @@ -368,11 +368,11 @@ def f(t): # that the string is a *raw* string and not to treat backslashes as # python escapes. matplotlib has a built-in TeX expression parser and # layout engine, and ships its own math fonts -- for details see -# :ref:`sphx_glr_tutorials_text_mathtext.py`. Thus you can use mathematical text across platforms +# :doc:`/tutorials/text/mathtext`. Thus you can use mathematical text across platforms # without requiring a TeX installation. For those who have LaTeX and # dvipng installed, you can also use LaTeX to format your text and # incorporate the output directly into your display figures or saved -# postscript -- see :ref:`sphx_glr_tutorials_text_usetex.py`. +# postscript -- see :doc:`/tutorials/text/usetex`. # # # Annotating text @@ -406,7 +406,7 @@ def f(t): # variety of other coordinate systems one can choose -- see # :ref:`annotations-tutorial` and :ref:`plotting-guide-annotation` for # details. More examples can be found in -# :ref:`sphx_glr_gallery_text_labels_and_annotations_annotation_demo.py`. +# :doc:`/gallery/text_labels_and_annotations/annotation_demo`. # # # Logarithmic and other nonlinear axes diff --git a/tutorials/introductory/sample_plots.py b/tutorials/introductory/sample_plots.py index 22738f2291c8..2fec0d223a35 100644 --- a/tutorials/introductory/sample_plots.py +++ b/tutorials/introductory/sample_plots.py @@ -362,7 +362,7 @@ Matplotlib's mathtext infrastructure is an independent implementation and does not require TeX or any external packages installed on your computer. See -the tutorial at :ref:`sphx_glr_tutorials_text_mathtext.py`. +the tutorial at :doc:`/tutorials/text/mathtext`. .. _screenshots_tex_demo: diff --git a/tutorials/introductory/usage.py b/tutorials/introductory/usage.py index 185f38d29b65..197caf06b9be 100644 --- a/tutorials/introductory/usage.py +++ b/tutorials/introductory/usage.py @@ -317,7 +317,7 @@ def my_plotter(ax, data1, data2, param_dict): # # # #. The ``backend`` parameter in your ``matplotlibrc`` file (see -# :ref:`sphx_glr_tutorials_introductory_customizing.py`):: +# :doc:`/tutorials/introductory/customizing`):: # # backend : WXAgg # use wxpython with antigrain (agg) rendering # @@ -515,7 +515,7 @@ def my_plotter(ax, data1, data2, param_dict): # that are called, and on a state variable that determines whether # matplotlib is in "interactive mode". The default Boolean value is set # by the :file:`matplotlibrc` file, and may be customized like any other -# configuration parameter (see :ref:`sphx_glr_tutorials_introductory_customizing.py`). It +# configuration parameter (see :doc:`/tutorials/introductory/customizing`). It # may also be set via :func:`matplotlib.interactive`, and its # value may be queried via :func:`matplotlib.is_interactive`. Turning # interactive mode on and off in the middle of a stream of plotting @@ -661,7 +661,7 @@ def my_plotter(ax, data1, data2, param_dict): # controlled by the ``path.simplify`` and # ``path.simplify_threshold`` parameters in your # ``matplotlibrc`` file (see -# :ref:`sphx_glr_tutorials_introductory_customizing.py` for +# :doc:`/tutorials/introductory/customizing` for # more information about the ``matplotlibrc`` file). # The ``path.simplify`` parameter is a boolean indicating whether # or not line segments are simplified at all. The @@ -698,7 +698,7 @@ def my_plotter(ax, data1, data2, param_dict): # interactive plotting (with maximal simplification) and another # style for publication quality plotting (with minimal # simplification) and activate them as necessary. See -# :ref:`sphx_glr_tutorials_introductory_customizing.py` for +# :doc:`/tutorials/introductory/customizing` for # instructions on how to perform these actions. # # The simplification works by iteratively merging line segments @@ -729,7 +729,7 @@ def my_plotter(ax, data1, data2, param_dict): # # The markevery argument allows for naive subsampling, or an # attempt at evenly spaced (along the *x* axis) sampling. See the -# :ref:`sphx_glr_gallery_lines_bars_and_markers_markevery_demo.py` +# :doc:`/gallery/lines_bars_and_markers/markevery_demo` # for more information. # # Splitting lines into smaller chunks diff --git a/tutorials/text/annotations.py b/tutorials/text/annotations.py index b9546582f089..a71b45377b44 100644 --- a/tutorials/text/annotations.py +++ b/tutorials/text/annotations.py @@ -94,7 +94,7 @@ For more on all the wild and wonderful things you can do with annotations, including fancy arrows, see :ref:`plotting-guide-annotation` -and :ref:`sphx_glr_gallery_text_labels_and_annotations_annotation_demo.py`. +and :doc:`/gallery/text_labels_and_annotations/annotation_demo`. Do not proceed unless you have already read :ref:`annotations-tutorial`, @@ -514,7 +514,7 @@ Annotation with Simple Coordinates 3 You may take a look at this example - :ref:`sphx_glr_gallery_text_labels_and_annotations_annotation_demo.py`. + :doc:`/gallery/text_labels_and_annotations/annotation_demo`. Using ConnectionPatch --------------------- diff --git a/tutorials/text/mathtext.py b/tutorials/text/mathtext.py index f18d0732edc9..de1a32f20aa1 100644 --- a/tutorials/text/mathtext.py +++ b/tutorials/text/mathtext.py @@ -12,7 +12,7 @@ layout engine is a fairly direct adaptation of the layout algorithms in Donald Knuth's TeX, so the quality is quite good (matplotlib also provides a ``usetex`` option for those who do want to call out to TeX -to generate their text (see :ref:`sphx_glr_tutorials_text_usetex.py`). +to generate their text (see :doc:`/tutorials/text/usetex`). """ ############################################################################### @@ -23,7 +23,7 @@ # (from (La)TeX), `STIX `_ fonts (with are designed # to blend well with Times), or a Unicode font that you provide. The mathtext # font can be selected with the customization variable ``mathtext.fontset`` (see -# :ref:`sphx_glr_tutorials_introductory_customizing.py`) +# :doc:`/tutorials/introductory/customizing`) # # .. note:: # On `"narrow" `_ builds @@ -63,8 +63,8 @@ # # have special meaning outside of math mode in TeX. Therefore, these # characters will behave differently depending on the rcParam -# ``text.usetex`` flag. See the :ref:`usetex tutorial -# ` for more information. +# ``text.usetex`` flag. See the :doc:`usetex tutorial +# ` for more information. # # Subscripts and superscripts # --------------------------- diff --git a/tutorials/text/text_props.py b/tutorials/text/text_props.py index a6adc42491b8..27567507db30 100644 --- a/tutorials/text/text_props.py +++ b/tutorials/text/text_props.py @@ -14,12 +14,12 @@ Property Value Type ========================== ====================================================================================================================== alpha `float` -backgroundcolor any matplotlib :ref:`color ` +backgroundcolor any matplotlib :doc:`color ` bbox `~matplotlib.patches.Rectangle` prop dict plus key ``'pad'`` which is a pad in points clip_box a matplotlib.transform.Bbox instance clip_on bool clip_path a `~matplotlib.path.Path` instance and a `~matplotlib.transforms.Transform` instance, a `~matplotlib.patches.Patch` -color any matplotlib :ref:`color ` +color any matplotlib :doc:`color ` family [ ``'serif'`` | ``'sans-serif'`` | ``'cursive'`` | ``'fantasy'`` | ``'monospace'`` ] fontproperties a `~matplotlib.font_manager.FontProperties` instance horizontalalignment or ha [ ``'center'`` | ``'right'`` | ``'left'`` ] @@ -217,8 +217,8 @@ # font.sans-serif: Source Han Sans TW, Arial, sans-serif # # To control the font used on per-artist basis use the ``'name'``, -# ``'fontname'`` or ``'fontproperties'`` kwargs documented :ref:`above -# `. +# ``'fontname'`` or ``'fontproperties'`` kwargs documented :doc:`above +# `. # # # On linux, `fc-list `__ can be a diff --git a/tutorials/text/usetex.py b/tutorials/text/usetex.py index bcb558b3df3e..bc30c5914df3 100644 --- a/tutorials/text/usetex.py +++ b/tutorials/text/usetex.py @@ -12,21 +12,21 @@ * PS * PDF -The LaTeX option is activated by setting ``text.usetex : True`` in -your rc settings. Text handling with matplotlib's LaTeX support is -slower than matplotlib's very capable :ref:`mathtext -`, but is more flexible, since different LaTeX -packages (font packages, math packages, etc.) can be used. The -results can be striking, especially when you take care to use the same -fonts in your figures as in the main document. +The LaTeX option is activated by setting ``text.usetex : True`` in your rc +settings. Text handling with matplotlib's LaTeX support is slower than +matplotlib's very capable :doc:`mathtext `, but is +more flexible, since different LaTeX packages (font packages, math packages, +etc.) can be used. The results can be striking, especially when you take care +to use the same fonts in your figures as in the main document. Matplotlib's LaTeX support requires a working LaTeX_ installation, dvipng_ (which may be included with your LaTeX installation), and Ghostscript_ (GPL Ghostscript 8.60 or later is recommended). The executables for these external dependencies must all be located on your :envvar:`PATH`. -There are a couple of options to mention, which can be changed using :ref:`rc -settings `. Here is an example matplotlibrc file:: +There are a couple of options to mention, which can be changed using +:doc:`rc settings `. Here is an example +matplotlibrc file:: font.family : serif font.serif : Times, Palatino, New Century Schoolbook, Bookman, Computer Modern Roman From fa5b1e1e8e4dbda3aea02b82351bb09707a3a7c8 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Tue, 29 May 2018 11:11:04 -0700 Subject: [PATCH 08/12] Merge pull request #11336 from timhoffm/raw-strings-for-docstrings-with-escape Use raw string literals for docstrings with escapes Conflicts: lib/matplotlib/artist.py - reject py2 incompatible changes lib/matplotlib/axes/_axes.py - also backports some documentation changes --- examples/shapes_and_collections/donut.py | 2 +- lib/matplotlib/artist.py | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/shapes_and_collections/donut.py b/examples/shapes_and_collections/donut.py index 794cd342b039..9afa26c85e6f 100644 --- a/examples/shapes_and_collections/donut.py +++ b/examples/shapes_and_collections/donut.py @@ -1,4 +1,4 @@ -""" +r""" ============= Mmh Donuts!!! ============= diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index 2cf785236f50..8dc1034bc707 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -1069,12 +1069,11 @@ class ArtistInspector(object): current values. """ def __init__(self, o): - """ - Initialize the artist inspector with an - :class:`~matplotlib.artist.Artist` or iterable of :class:`Artists`. - If an iterable is used, we assume it is a homogeneous sequence (all - :class:`Artists` are of the same type) and it is your responsibility - to make sure this is so. + r""" + Initialize the artist inspector with an `Artist` or an iterable of + `Artist`\s. If an iterable is used, we assume it is a homogeneous + sequence (all `Artists` are of the same type) and it is your + responsibility to make sure this is so. """ if not isinstance(o, Artist): if cbook.iterable(o): From 6133a7d5c563568238eb9e0a958367dba88d7046 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 10 Jun 2018 09:59:05 -0500 Subject: [PATCH 09/12] Merge pull request #11407 from anntzer/step-markers FIX: Properly position markers in step plots. Conflicts: lib/matplotlib/tests/test_lines.py - conflict due to adding imports around (removed on master) __future__ and six --- lib/matplotlib/lines.py | 22 ++++++++++++++++++---- lib/matplotlib/tests/test_lines.py | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index b885ec1713dc..76db9b9bee74 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -744,8 +744,8 @@ def draw(self, renderer): subslice = slice(max(i0 - 1, 0), i1 + 1) self.ind_offset = subslice.start self._transform_path(subslice) - - transf_path = self._get_transformed_path() + else: + subslice = None if self.get_path_effects(): from matplotlib.patheffects import PathEffectRenderer @@ -753,7 +753,8 @@ def draw(self, renderer): renderer.open_group('line2d', self.get_gid()) if self._lineStyles[self._linestyle] != '_draw_nothing': - tpath, affine = transf_path.get_transformed_path_and_affine() + tpath, affine = (self._get_transformed_path() + .get_transformed_path_and_affine()) if len(tpath.vertices): gc = renderer.new_gc() self._set_gc_clip(gc) @@ -801,7 +802,20 @@ def draw(self, renderer): gc.set_foreground(ec_rgba, isRGBA=True) marker = self._marker - tpath, affine = transf_path.get_transformed_points_and_affine() + + # Markers *must* be drawn ignoring the drawstyle (but don't pay the + # recaching if drawstyle is already "default"). + if self.get_drawstyle() != "default": + with cbook._setattr_cm( + self, _drawstyle="default", _transformed_path=None): + self.recache() + self._transform_path(subslice) + tpath, affine = (self._get_transformed_path() + .get_transformed_path_and_affine()) + else: + tpath, affine = (self._get_transformed_path() + .get_transformed_path_and_affine()) + if len(tpath.vertices): # subsample the markers if markevery is not None markevery = self.get_markevery() diff --git a/lib/matplotlib/tests/test_lines.py b/lib/matplotlib/tests/test_lines.py index ca9c8187c519..e263d948c2f6 100644 --- a/lib/matplotlib/tests/test_lines.py +++ b/lib/matplotlib/tests/test_lines.py @@ -1,8 +1,10 @@ """ Tests specific to the lines module. """ + from __future__ import absolute_import, division, print_function +from io import BytesIO import itertools import matplotlib.lines as mlines import pytest @@ -197,3 +199,15 @@ def test_nan_is_sorted(): assert line._is_sorted(np.array([1, 2, 3])) assert line._is_sorted(np.array([1, np.nan, 3])) assert not line._is_sorted([3, 5] + [np.nan] * 100 + [0, 2]) + + +def test_step_markers(): + fig, ax = plt.subplots() + ax.step([0, 1], "-o") + buf1 = BytesIO() + fig.savefig(buf1) + fig, ax = plt.subplots() + ax.plot([0, 0, 1], [0, 1, 1], "-o", markevery=[0, 2]) + buf2 = BytesIO() + fig.savefig(buf2) + assert buf1.getvalue() == buf2.getvalue() From 86a3bace3693bccdf741c9d2c5ccc500e799e453 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 5 Jul 2018 19:07:04 -0400 Subject: [PATCH 10/12] Merge pull request #11580 from timhoffm/subplots DOC: Use plt.subplots() Conflicts: lib/matplotlib/tests/test_backends_interactive.py - only backported the minimal change tutorials/advanced/transforms_tutorial.py - only backported the minimal change tutorials/text/pgf.py - only backported the minimal change --- .../lines_bars_and_markers/simple_plot.py | 2 - examples/misc/load_converter.py | 3 +- examples/pyplots/annotate_transform.py | 3 +- examples/pyplots/auto_subplots_adjust.py | 3 +- .../tick_labels_from_values.py | 3 +- lib/matplotlib/lines.py | 3 +- lib/matplotlib/mlab.py | 3 +- lib/matplotlib/tests/test_artist.py | 3 +- lib/matplotlib/tests/test_axes.py | 117 +++++------------- lib/matplotlib/tests/test_backend_svg.py | 3 +- .../tests/test_backends_interactive.py | 6 +- lib/matplotlib/tests/test_colorbar.py | 3 +- .../tests/test_constrainedlayout.py | 1 - lib/matplotlib/tests/test_contour.py | 24 ++-- lib/matplotlib/tests/test_cycles.py | 18 +-- lib/matplotlib/tests/test_image.py | 40 ++---- lib/matplotlib/tests/test_tightlayout.py | 6 +- lib/matplotlib/tests/test_ttconv.py | 3 +- tutorials/advanced/path_tutorial.py | 10 +- tutorials/advanced/transforms_tutorial.py | 14 +-- tutorials/intermediate/artists.py | 7 +- tutorials/introductory/usage.py | 3 +- 22 files changed, 86 insertions(+), 192 deletions(-) diff --git a/examples/lines_bars_and_markers/simple_plot.py b/examples/lines_bars_and_markers/simple_plot.py index 20f2875d6a9d..f51e16015b2e 100644 --- a/examples/lines_bars_and_markers/simple_plot.py +++ b/examples/lines_bars_and_markers/simple_plot.py @@ -14,8 +14,6 @@ t = np.arange(0.0, 2.0, 0.01) s = 1 + np.sin(2 * np.pi * t) -# Note that using plt.subplots below is equivalent to using -# fig = plt.figure() and then ax = fig.add_subplot(111) fig, ax = plt.subplots() ax.plot(t, s) diff --git a/examples/misc/load_converter.py b/examples/misc/load_converter.py index 1534a11b5a0f..f6201ac2d650 100644 --- a/examples/misc/load_converter.py +++ b/examples/misc/load_converter.py @@ -18,8 +18,7 @@ converters={0: bytespdate2num('%d-%b-%y')}, skiprows=1, usecols=(0, 2), unpack=True) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() ax.plot_date(dates, closes, '-') fig.autofmt_xdate() plt.show() diff --git a/examples/pyplots/annotate_transform.py b/examples/pyplots/annotate_transform.py index 458da2d1e1f1..2fd6d3722a8d 100644 --- a/examples/pyplots/annotate_transform.py +++ b/examples/pyplots/annotate_transform.py @@ -10,8 +10,7 @@ x = np.arange(0, 10, 0.005) y = np.exp(-x/2.) * np.sin(2*np.pi*x) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() ax.plot(x, y) ax.set_xlim(0, 10) ax.set_ylim(-1, 1) diff --git a/examples/pyplots/auto_subplots_adjust.py b/examples/pyplots/auto_subplots_adjust.py index bb430827bef3..55397f3f3475 100644 --- a/examples/pyplots/auto_subplots_adjust.py +++ b/examples/pyplots/auto_subplots_adjust.py @@ -6,8 +6,7 @@ """ import matplotlib.pyplot as plt import matplotlib.transforms as mtransforms -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() ax.plot(range(10)) ax.set_yticks((2,5,7)) labels = ax.set_yticklabels(('really, really, really', 'long', 'labels')) diff --git a/examples/ticks_and_spines/tick_labels_from_values.py b/examples/ticks_and_spines/tick_labels_from_values.py index fca78eb46ff1..c504796b7a1b 100644 --- a/examples/ticks_and_spines/tick_labels_from_values.py +++ b/examples/ticks_and_spines/tick_labels_from_values.py @@ -17,8 +17,7 @@ import matplotlib.pyplot as plt from matplotlib.ticker import FuncFormatter, MaxNLocator -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() xs = range(26) ys = range(26) labels = list('abcdefghijklmnopqrstuvwxyz') diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index 76db9b9bee74..dac18d498552 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -1446,8 +1446,7 @@ def process_selected(self, ind, xs, ys): self.markers.set_data(xs, ys) self.canvas.draw() - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() x, y = np.random.rand(2, 30) line, = ax.plot(x, y, 'bs-', picker=5) diff --git a/lib/matplotlib/mlab.py b/lib/matplotlib/mlab.py index 04f65e3a59f5..bf4bc52a9314 100644 --- a/lib/matplotlib/mlab.py +++ b/lib/matplotlib/mlab.py @@ -3898,8 +3898,7 @@ def cross_from_below(x, threshold): t = np.arange(0.0, 2.0, 0.1) s = np.sin(2*np.pi*t) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.plot(t, s, '-o') ax.axhline(0.5) ax.axhline(-0.5) diff --git a/lib/matplotlib/tests/test_artist.py b/lib/matplotlib/tests/test_artist.py index 8d1a0129451b..e6aff72bf1d8 100644 --- a/lib/matplotlib/tests/test_artist.py +++ b/lib/matplotlib/tests/test_artist.py @@ -131,8 +131,7 @@ def test_cull_markers(): x = np.random.random(20000) y = np.random.random(20000) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.plot(x, y, 'k.') ax.set_xlim(2, 3) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index c71aa6bfe844..2fa6c2c94b97 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -815,9 +815,7 @@ def test_axhspan_epoch(): remove_text=True, extensions=['png']) def test_hexbin_extent(): # this test exposes sf bug 2856228 - fig = plt.figure() - - ax = fig.add_subplot(111) + fig, ax = plt.subplots() data = (np.arange(2000) / 2000).reshape((2, 1000)) x, y = data @@ -826,8 +824,7 @@ def test_hexbin_extent(): # Reuse testcase from above for a labeled data test data = {"x": x, "y": y} - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.hexbin("x", "y", extent=[.1, .3, .6, .7], data=data) @@ -846,9 +843,7 @@ def __init__(self, x, y): self.x = x self.y = y - fig = plt.figure() - - ax = fig.add_subplot(111) + fig, ax = plt.subplots() data = (np.arange(200) / 200).reshape((2, 100)) x, y = data hb = ax.hexbin(x, y, extent=[.1, .3, .6, .7], picker=-1) @@ -861,14 +856,13 @@ def __init__(self, x, y): extensions=['png']) def test_hexbin_log(): # Issue #1636 - fig = plt.figure() - np.random.seed(0) n = 100000 x = np.random.standard_normal(n) y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n) y = np.power(2, y * 0.5) - ax = fig.add_subplot(111) + + fig, ax = plt.subplots() ax.hexbin(x, y, yscale='log') @@ -876,8 +870,7 @@ def test_inverted_limits(): # Test gh:1553 # Calling invert_xaxis prior to plotting should not disable autoscaling # while still maintaining the inverted direction - fig = plt.figure() - ax = fig.gca() + fig, ax = plt.subplots() ax.invert_xaxis() ax.plot([-5, -3, 2, 4], [1, 2, -3, 5]) @@ -885,8 +878,7 @@ def test_inverted_limits(): assert ax.get_ylim() == (-3, 5) plt.close() - fig = plt.figure() - ax = fig.gca() + fig, ax = plt.subplots() ax.invert_yaxis() ax.plot([-5, -3, 2, 4], [1, 2, -3, 5]) @@ -905,8 +897,7 @@ def test_nonfinite_limits(): finally: np.seterr(**olderr) x[len(x)//2] = np.nan - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.plot(x, y) @@ -921,9 +912,7 @@ def test_imshow(): r = np.sqrt(x**2+y**2-x*y) # Create a contour plot at N/4 and extract both the clip path and transform - fig = plt.figure() - ax = fig.add_subplot(111) - + fig, ax = plt.subplots() ax.imshow(r) # Reuse testcase from above for a labeled data test @@ -945,8 +934,7 @@ def test_imshow_clip(): r = np.sqrt(x**2+y**2-x*y) # Create a contour plot at N/4 and extract both the clip path and transform - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() c = ax.contour(r, [N/4]) x = c.collections[0] @@ -967,8 +955,7 @@ def test_polycollection_joinstyle(): from matplotlib import collections as mcoll - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() verts = np.array([[1, 1], [1, 2], [2, 2], [2, 1]]) c = mcoll.PolyCollection([verts], linewidths=40) ax.add_collection(c) @@ -988,8 +975,7 @@ def test_polycollection_joinstyle(): ] ) def test_fill_between_input(x, y1, y2): - fig = plt.figure() - ax = fig.add_subplot(211) + fig, ax = plt.subplots() with pytest.raises(ValueError): ax.fill_between(x, y1, y2) @@ -1006,8 +992,7 @@ def test_fill_between_input(x, y1, y2): ] ) def test_fill_betweenx_input(y, x1, x2): - fig = plt.figure() - ax = fig.add_subplot(211) + fig, ax = plt.subplots() with pytest.raises(ValueError): ax.fill_betweenx(y, x1, x2) @@ -1019,23 +1004,21 @@ def test_fill_between_interpolate(): y1 = np.sin(2*np.pi*x) y2 = 1.2*np.sin(4*np.pi*x) - fig = plt.figure() - ax = fig.add_subplot(211) - ax.plot(x, y1, x, y2, color='black') - ax.fill_between(x, y1, y2, where=y2 >= y1, facecolor='white', hatch='/', - interpolate=True) - ax.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', - interpolate=True) + fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True) + ax1.plot(x, y1, x, y2, color='black') + ax1.fill_between(x, y1, y2, where=y2 >= y1, facecolor='white', hatch='/', + interpolate=True) + ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', + interpolate=True) # Test support for masked arrays. y2 = np.ma.masked_greater(y2, 1.0) # Test that plotting works for masked arrays with the first element masked y2[0] = np.ma.masked - ax1 = fig.add_subplot(212, sharex=ax) - ax1.plot(x, y1, x, y2, color='black') - ax1.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green', + ax2.plot(x, y1, x, y2, color='black') + ax2.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green', interpolate=True) - ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', + ax2.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True) @@ -1046,8 +1029,7 @@ def test_fill_between_interpolate_decreasing(): t = np.array([9.4, 7, 2.2]) prof = np.array([7.9, 6.6, 3.8]) - fig = plt.figure(figsize=(9, 9)) - ax = fig.add_subplot(1, 1, 1) + fig, ax = plt.subplots(figsize=(9, 9)) ax.plot(t, p, 'tab:red') ax.plot(prof, p, 'k') @@ -1066,8 +1048,7 @@ def test_symlog(): x = np.array([0, 1, 2, 4, 6, 9, 12, 24]) y = np.array([1000000, 500000, 100000, 100, 5, 0, 0, 0]) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.plot(x, y) ax.set_yscale('symlog') ax.set_xscale('linear') @@ -1080,37 +1061,12 @@ def test_symlog2(): # Numbers from -50 to 50, with 0.1 as step x = np.arange(-50, 50, 0.001) - fig = plt.figure() - ax = fig.add_subplot(511) - # Plots a simple linear function 'f(x) = x' - ax.plot(x, x) - ax.set_xscale('symlog', linthreshx=20.0) - ax.grid(True) - - ax = fig.add_subplot(512) - # Plots a simple linear function 'f(x) = x' - ax.plot(x, x) - ax.set_xscale('symlog', linthreshx=2.0) - ax.grid(True) - - ax = fig.add_subplot(513) - # Plots a simple linear function 'f(x) = x' - ax.plot(x, x) - ax.set_xscale('symlog', linthreshx=1.0) - ax.grid(True) - - ax = fig.add_subplot(514) - # Plots a simple linear function 'f(x) = x' - ax.plot(x, x) - ax.set_xscale('symlog', linthreshx=0.1) - ax.grid(True) - - ax = fig.add_subplot(515) - # Plots a simple linear function 'f(x) = x' - ax.plot(x, x) - ax.set_xscale('symlog', linthreshx=0.01) - ax.grid(True) - ax.set_ylim(-0.1, 0.1) + fig, axs = plt.subplots(5, 1) + for ax, linthreshx in zip(axs, [20., 2., 1., 0.1, 0.01]): + ax.plot(x, x) + ax.set_xscale('symlog', linthreshx=linthreshx) + ax.grid(True) + axs[-1].set_ylim(-0.1, 0.1) def test_pcolorargs_5205(): @@ -1142,15 +1098,10 @@ def test_pcolormesh(): # The color array can include masked values: Zm = ma.masked_where(np.abs(Qz) < 0.5 * np.max(Qz), Z) - fig = plt.figure() - ax = fig.add_subplot(131) - ax.pcolormesh(Qx, Qz, Z, lw=0.5, edgecolors='k') - - ax = fig.add_subplot(132) - ax.pcolormesh(Qx, Qz, Z, lw=2, edgecolors=['b', 'w']) - - ax = fig.add_subplot(133) - ax.pcolormesh(Qx, Qz, Z, shading="gouraud") + fig, (ax1, ax2, ax3) = plt.subplots(1, 3) + ax1.pcolormesh(Qx, Qz, Z, lw=0.5, edgecolors='k') + ax2.pcolormesh(Qx, Qz, Z, lw=2, edgecolors=['b', 'w']) + ax3.pcolormesh(Qx, Qz, Z, shading="gouraud") @image_comparison(baseline_images=['pcolormesh_datetime_axis'], diff --git a/lib/matplotlib/tests/test_backend_svg.py b/lib/matplotlib/tests/test_backend_svg.py index 0facf2abd18f..e0cbdfa8bce1 100644 --- a/lib/matplotlib/tests/test_backend_svg.py +++ b/lib/matplotlib/tests/test_backend_svg.py @@ -22,8 +22,7 @@ def test_visibility(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() x = np.linspace(0, 4 * np.pi, 50) y = np.sin(x) diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py index bd1cc5f108b7..df7a5d08a10b 100644 --- a/lib/matplotlib/tests/test_backends_interactive.py +++ b/lib/matplotlib/tests/test_backends_interactive.py @@ -40,9 +40,9 @@ def _get_testable_interactive_backends(): import sys from matplotlib import pyplot as plt -fig = plt.figure() -ax = fig.add_subplot(111) -ax.plot([1,2,3], [1,3,1]) +fig, ax = plt.subplots() +ax.plot([0, 1], [2, 3]) + fig.canvas.mpl_connect("draw_event", lambda event: sys.exit()) plt.show() """ diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 539ee8c83416..12a9bed3be3b 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -212,8 +212,7 @@ def test_remove_from_figure(use_gridspec): """ Test `remove_from_figure` with the specified ``use_gridspec`` setting """ - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() sc = ax.scatter([1, 2], [3, 4], cmap="spring") sc.set_array(np.array([5, 6])) pre_figbox = np.array(ax.figbox) diff --git a/lib/matplotlib/tests/test_constrainedlayout.py b/lib/matplotlib/tests/test_constrainedlayout.py index 2f536b9b4c91..fcf633a0821d 100644 --- a/lib/matplotlib/tests/test_constrainedlayout.py +++ b/lib/matplotlib/tests/test_constrainedlayout.py @@ -212,7 +212,6 @@ def test_constrained_layout9(): 'Test for handling suptitle and for sharex and sharey' fig, axs = plt.subplots(2, 2, constrained_layout=True, sharex=False, sharey=False) - # ax = fig.add_subplot(111) for ax in axs.flatten(): pcm = example_pcolor(ax, fontsize=24) ax.set_xlabel('') diff --git a/lib/matplotlib/tests/test_contour.py b/lib/matplotlib/tests/test_contour.py index 35d33b972532..42903ac6897e 100644 --- a/lib/matplotlib/tests/test_contour.py +++ b/lib/matplotlib/tests/test_contour.py @@ -16,8 +16,7 @@ def test_contour_shape_1d_valid(): y = np.arange(9) z = np.random.random((9, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.contour(x, y, z) @@ -28,8 +27,7 @@ def test_contour_shape_2d_valid(): xg, yg = np.meshgrid(x, y) z = np.random.random((9, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.contour(xg, yg, z) @@ -39,8 +37,7 @@ def test_contour_shape_mismatch_1(): y = np.arange(9) z = np.random.random((9, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() with pytest.raises(TypeError) as excinfo: ax.contour(x, y, z) @@ -53,8 +50,7 @@ def test_contour_shape_mismatch_2(): y = np.arange(10) z = np.random.random((9, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() with pytest.raises(TypeError) as excinfo: ax.contour(x, y, z) @@ -68,8 +64,7 @@ def test_contour_shape_mismatch_3(): xg, yg = np.meshgrid(x, y) z = np.random.random((9, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() with pytest.raises(TypeError) as excinfo: ax.contour(xg, y, z) @@ -86,8 +81,7 @@ def test_contour_shape_mismatch_4(): b = np.random.random((9, 9)) z = np.random.random((9, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() with pytest.raises(TypeError) as excinfo: ax.contour(b, g, z) @@ -106,8 +100,7 @@ def test_contour_shape_invalid_1(): y = np.random.random((3, 3, 3)) z = np.random.random((9, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() with pytest.raises(TypeError) as excinfo: ax.contour(x, y, z) @@ -120,8 +113,7 @@ def test_contour_shape_invalid_2(): y = np.random.random((3, 3, 3)) z = np.random.random((3, 3, 3)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() with pytest.raises(TypeError) as excinfo: ax.contour(x, y, z) diff --git a/lib/matplotlib/tests/test_cycles.py b/lib/matplotlib/tests/test_cycles.py index 95611f36c0e7..dfa0f7c796f1 100644 --- a/lib/matplotlib/tests/test_cycles.py +++ b/lib/matplotlib/tests/test_cycles.py @@ -12,8 +12,7 @@ @image_comparison(baseline_images=['color_cycle_basic'], remove_text=True, extensions=['png']) def test_colorcycle_basic(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.set_prop_cycle(cycler('color', ['r', 'g', 'y'])) xs = np.arange(10) ys = 0.25 * xs + 2 @@ -30,8 +29,7 @@ def test_colorcycle_basic(): @image_comparison(baseline_images=['marker_cycle', 'marker_cycle'], remove_text=True, extensions=['png']) def test_marker_cycle(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.set_prop_cycle(cycler('c', ['r', 'g', 'y']) + cycler('marker', ['.', '*', 'x'])) xs = np.arange(10) @@ -45,8 +43,7 @@ def test_marker_cycle(): ax.plot(xs, ys, label='red2 dot', lw=4, ms=16) ax.legend(loc='upper left') - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() # Test keyword arguments, numpy arrays, and generic iterators ax.set_prop_cycle(c=np.array(['r', 'g', 'y']), marker=iter(['.', '*', 'x'])) @@ -65,8 +62,7 @@ def test_marker_cycle(): @image_comparison(baseline_images=['lineprop_cycle_basic'], remove_text=True, extensions=['png']) def test_linestylecycle_basic(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.set_prop_cycle(cycler('ls', ['-', '--', ':'])) xs = np.arange(10) ys = 0.25 * xs + 2 @@ -83,8 +79,7 @@ def test_linestylecycle_basic(): @image_comparison(baseline_images=['fill_cycle_basic'], remove_text=True, extensions=['png']) def test_fillcycle_basic(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.set_prop_cycle(cycler('c', ['r', 'g', 'y']) + cycler('hatch', ['xx', 'O', '|-']) + cycler('linestyle', ['-', '--', ':'])) @@ -103,8 +98,7 @@ def test_fillcycle_basic(): @image_comparison(baseline_images=['fill_cycle_ignore'], remove_text=True, extensions=['png']) def test_fillcycle_ignore(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.set_prop_cycle(cycler('color', ['r', 'g', 'y']) + cycler('hatch', ['xx', 'O', '|-']) + cycler('marker', ['.', '*', 'D'])) diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 26e3b4a7ea26..e6da25789f0b 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -105,8 +105,7 @@ def test_figimage1(): def test_image_python_io(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.plot([1,2,3]) buffer = io.BytesIO() fig.savefig(buffer) @@ -285,8 +284,7 @@ def test_image_clip(): def test_image_cliprect(): import matplotlib.patches as patches - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() d = [[1,2],[3,4]] im = ax.imshow(d, extent=(0,5,0,5)) @@ -297,12 +295,8 @@ def test_image_cliprect(): @image_comparison(baseline_images=['imshow'], remove_text=True, style='mpl20') def test_imshow(): - import numpy as np - import matplotlib.pyplot as plt - - fig = plt.figure() + fig, ax = plt.subplots() arr = np.arange(100).reshape((10, 10)) - ax = fig.add_subplot(111) ax.imshow(arr, interpolation="bilinear", extent=(1,2,1,2)) ax.set_xlim(0,3) ax.set_ylim(0,3) @@ -329,8 +323,7 @@ def test_image_shift(): tMin=734717.945208 tMax=734717.946366 - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.imshow(imgData, norm=LogNorm(), interpolation='none', extent=(tMin, tMax, 1, 100)) ax.set_aspect('auto') @@ -368,8 +361,7 @@ def test_image_edges(): remove_text=True, style='mpl20') def test_image_composite_background(): - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() arr = np.arange(12).reshape(4, 3) ax.imshow(arr, extent=[0, 2, 15, 0]) ax.imshow(arr, extent=[4, 6, 15, 0]) @@ -384,8 +376,7 @@ def test_image_composite_alpha(): Tests that the alpha value is recognized and correctly applied in the process of compositing images together. """ - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() arr = np.zeros((11, 21, 4)) arr[:, :, 0] = 1 arr[:, :, 3] = np.concatenate((np.arange(0, 1.1, 0.1), np.arange(0, 1, 0.1)[::-1])) @@ -413,9 +404,6 @@ def test_rasterize_dpi(): # when images end up in the wrong place in case of non-standard dpi setting. # Instead of high-res rasterization i use low-res. Therefore the fact that the # resolution is non-standard is easily checked by image_comparison. - import numpy as np - import matplotlib.pyplot as plt - img = np.asarray([[1, 2], [3, 4]]) fig, axes = plt.subplots(1, 3, figsize = (3, 1)) @@ -445,7 +433,7 @@ def test_bbox_image_inverted(): # This is just used to produce an image to feed to BboxImage image = np.arange(100).reshape((10, 10)) - ax = plt.subplot(111) + fig, ax = plt.subplots() bbox_im = BboxImage( TransformedBbox(Bbox([[100, 100], [0, 0]]), ax.transData)) bbox_im.set_data(image) @@ -470,8 +458,7 @@ def test_get_window_extent_for_AxisImage(): im = np.array([[0.25, 0.75, 1.0, 0.75], [0.1, 0.65, 0.5, 0.4], [0.6, 0.3, 0.0, 0.2], [0.7, 0.9, 0.4, 0.6]]) - fig = plt.figure(figsize=(10, 10), dpi=100) - ax = plt.subplot() + fig, ax = plt.subplots(figsize=(10, 10), dpi=100) ax.set_position([0, 0, 1, 1]) ax.set_xlim(0, 1) ax.set_ylim(0, 1) @@ -492,8 +479,7 @@ def test_zoom_and_clip_upper_origin(): image = np.arange(100) image = image.reshape((10, 10)) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.imshow(image) ax.set_ylim(2.0, -0.5) ax.set_xlim(-0.5, 2.0) @@ -642,9 +628,7 @@ def test_log_scale_image(recwarn): Z = np.zeros((10, 10)) Z[::2] = 1 - fig = plt.figure() - ax = fig.add_subplot(111) - + fig, ax = plt.subplots() ax.imshow(Z, extent=[1, 100, 1, 100], cmap='viridis', vmax=1, vmin=-1) ax.set_yscale('log') @@ -936,8 +920,8 @@ def test_composite(fmt, counted, composite_image, count): # (on a single set of axes) into a single composite image. X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) Z = np.sin(Y ** 2) - fig = plt.figure() - ax = fig.add_subplot(1, 1, 1) + + fig, ax = plt.subplots() ax.set_xlim(0, 3) ax.imshow(Z, extent=[0, 1, 0, 1]) ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) diff --git a/lib/matplotlib/tests/test_tightlayout.py b/lib/matplotlib/tests/test_tightlayout.py index 0516971d2d9c..4ae8aa5ef792 100644 --- a/lib/matplotlib/tests/test_tightlayout.py +++ b/lib/matplotlib/tests/test_tightlayout.py @@ -22,8 +22,7 @@ def example_plot(ax, fontsize=12): @image_comparison(baseline_images=['tight_layout1']) def test_tight_layout1(): 'Test tight_layout for a single subplot' - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() example_plot(ax, fontsize=24) plt.tight_layout() @@ -136,9 +135,8 @@ def test_tight_layout6(): @image_comparison(baseline_images=['tight_layout7']) def test_tight_layout7(): # tight layout with left and right titles - fig = plt.figure() fontsize = 24 - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.plot([1, 2]) ax.locator_params(nbins=3) ax.set_xlabel('x-label', fontsize=fontsize) diff --git a/lib/matplotlib/tests/test_ttconv.py b/lib/matplotlib/tests/test_ttconv.py index de4c579d9033..d2299bb520cc 100644 --- a/lib/matplotlib/tests/test_ttconv.py +++ b/lib/matplotlib/tests/test_ttconv.py @@ -16,8 +16,7 @@ def test_truetype_conversion(): fontname = os.path.abspath(fontname) fontprop = FontProperties(fname=fontname, size=80) matplotlib.rcParams['pdf.fonttype'] = 3 - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.text(0, 0, "ABCDE", fontproperties=fontprop) ax.set_xticks([]) ax.set_yticks([]) diff --git a/tutorials/advanced/path_tutorial.py b/tutorials/advanced/path_tutorial.py index a440a8b2aeaf..e0444c5e1cae 100644 --- a/tutorials/advanced/path_tutorial.py +++ b/tutorials/advanced/path_tutorial.py @@ -36,8 +36,7 @@ path = Path(verts, codes) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() patch = patches.PathPatch(path, facecolor='orange', lw=2) ax.add_patch(patch) ax.set_xlim(-2, 2) @@ -91,8 +90,7 @@ path = Path(verts, codes) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() patch = patches.PathPatch(path, facecolor='none', lw=2) ax.add_patch(patch) @@ -182,9 +180,7 @@ import matplotlib.patches as patches import matplotlib.path as path -fig = plt.figure() -ax = fig.add_subplot(111) - +fig, ax = plt.subplots() # Fixing random state for reproducibility np.random.seed(19680801) diff --git a/tutorials/advanced/transforms_tutorial.py b/tutorials/advanced/transforms_tutorial.py index b0f39b7eae92..2ea03567d70b 100644 --- a/tutorials/advanced/transforms_tutorial.py +++ b/tutorials/advanced/transforms_tutorial.py @@ -75,8 +75,7 @@ x = np.arange(0, 10, 0.005) y = np.exp(-x/2.) * np.sin(2*np.pi*x) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() ax.plot(x, y) ax.set_xlim(0, 10) ax.set_ylim(-1, 1) @@ -124,8 +123,7 @@ x = np.arange(0, 10, 0.005) y = np.exp(-x/2.) * np.sin(2*np.pi*x) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() ax.plot(x, y) ax.set_xlim(0, 10) ax.set_ylim(-1, 1) @@ -231,8 +229,8 @@ import matplotlib.patches as patches -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() + x, y = 10*np.random.rand(2, 1000) ax.plot(x, y, 'go') # plot some data in data coordinates @@ -265,9 +263,7 @@ import matplotlib.transforms as transforms -fig = plt.figure() -ax = fig.add_subplot(111) - +fig, ax = plt.subplots() x = np.random.randn(1000) ax.hist(x, 30) diff --git a/tutorials/intermediate/artists.py b/tutorials/intermediate/artists.py index aa5e04418edb..547ddccf0d18 100644 --- a/tutorials/intermediate/artists.py +++ b/tutorials/intermediate/artists.py @@ -437,9 +437,7 @@ class in the matplotlib API, and the one you will be working with most # # .. sourcecode:: ipython # -# In [261]: fig = plt.figure() -# -# In [262]: ax = fig.add_subplot(111) +# In [262]: fig, ax = plt.subplots() # # # create a rectangle instance # In [263]: rect = matplotlib.patches.Rectangle( (1,1), width=5, height=12) @@ -683,8 +681,7 @@ class in the matplotlib API, and the one you will be working with most # Fixing random state for reproducibility np.random.seed(19680801) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() ax.plot(100*np.random.rand(20)) formatter = ticker.FormatStrFormatter('$%1.2f') diff --git a/tutorials/introductory/usage.py b/tutorials/introductory/usage.py index 197caf06b9be..87c2f62c0c05 100644 --- a/tutorials/introductory/usage.py +++ b/tutorials/introductory/usage.py @@ -220,8 +220,7 @@ x = np.arange(0, 10, 0.2) y = np.sin(x) -fig = plt.figure() -ax = fig.add_subplot(111) +fig, ax = plt.subplots() ax.plot(x, y) plt.show() From 648a04e871122f815fde8bf6dba501cdc5248940 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sat, 7 Jul 2018 13:11:22 -0400 Subject: [PATCH 11/12] Merge pull request #11588 from jklymak/doc-warn-if-CL-plus-TL DOC: warn if user is using constrained layout and uses subplots_adjust Conflicts: lib/matplotlib/figure.py - signature on master has changed to explicit kwargs, conflict due to that change. --- lib/matplotlib/figure.py | 7 +++++++ lib/matplotlib/tests/test_figure.py | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index fb734a2fdd21..55feb32a1139 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -2090,7 +2090,14 @@ def subplots_adjust(self, *args, **kwargs): *None*) and update the subplot locations. """ + if self.get_constrained_layout(): + self.set_constrained_layout(False) + warnings.warn("This figure was using constrained_layout==True, " + "but that is incompatible with subplots_adjust and " + "or tight_layout: setting " + "constrained_layout==False. ") self.subplotpars.update(*args, **kwargs) + for ax in self.axes: if not isinstance(ax, SubplotBase): # Check if sharing a subplots axis diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index 229ce192cc75..69752e17d666 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -376,6 +376,14 @@ def test_figure_repr(): assert repr(fig) == "
" +def test_warn_cl_plus_tl(): + 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()) + + @pytest.mark.skipif(sys.version_info < (3, 6), reason="requires Python 3.6+") @pytest.mark.parametrize("fmt", ["png", "pdf", "ps", "eps", "svg"]) def test_fspath(fmt, tmpdir): From 42bd99abbcf97ed20ffcb19640d783a252875bd2 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sat, 4 Aug 2018 20:11:32 -0400 Subject: [PATCH 12/12] ENH: backport cbook._setattr_cm This context manager was added to master in 690b21345b1a61158b8800d1f7380d063a6f970e via #10314. We do not want to backport that entire commit, however the backport of #11407 requires this context manger. It is private and self contained to low-risk to backport --- lib/matplotlib/cbook/__init__.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index ce65b8c5ec4d..dcb2d0549dea 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -2832,3 +2832,21 @@ def _str_lower_equal(obj, s): cannot be used in a boolean context. """ return isinstance(obj, six.string_types) and obj.lower() == s + + +@contextlib.contextmanager +def _setattr_cm(obj, **kwargs): + """Temporarily set some attributes; restore original state at context exit. + """ + sentinel = object() + origs = [(attr, getattr(obj, attr, sentinel)) for attr in kwargs] + try: + for attr, val in kwargs.items(): + setattr(obj, attr, val) + yield + finally: + for attr, orig in origs: + if orig is sentinel: + delattr(obj, attr) + else: + setattr(obj, attr, orig)