diff --git a/.flake8 b/.flake8
index b139c87d0490..630d7dfda16e 100644
--- a/.flake8
+++ b/.flake8
@@ -23,7 +23,7 @@ exclude =
per-file-ignores =
setup.py: E402
- setupext.py: E302, E501
+ setupext.py: E501
tools/compare_backend_driver_results.py: E501
tools/subset.py: E221, E231, E251, E261, E302, E501, E701
diff --git a/doc-requirements.txt b/doc-requirements.txt
index 58a5c698043b..c0ee2014cf64 100644
--- a/doc-requirements.txt
+++ b/doc-requirements.txt
@@ -6,7 +6,7 @@
# Install the documentation requirements with:
# pip install -r doc-requirements.txt
#
-sphinx>=1.3,!=1.5.0,!=1.6.4,!=1.7.3,<1.8
+sphinx>=1.3,!=1.5.0,!=1.6.4,!=1.7.3
colorspacious
ipython
ipywidgets
diff --git a/doc/conf.py b/doc/conf.py
index 5b2395702e62..c67b3f335ee5 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -84,7 +84,10 @@ def _check_deps():
autosummary_generate = True
autodoc_docstring_signature = True
-autodoc_default_flags = ['members', 'undoc-members']
+if sphinx.version_info < (1, 8):
+ autodoc_default_flags = ['members', 'undoc-members']
+else:
+ autodoc_default_options = {'members': None, 'undoc-members': None}
intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
diff --git a/doc/sphinxext/github.py b/doc/sphinxext/github.py
index 8f0ffc0d9782..75c5ce10ae9d 100644
--- a/doc/sphinxext/github.py
+++ b/doc/sphinxext/github.py
@@ -75,7 +75,6 @@ def ghissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
app = inliner.document.settings.env.app
- #app.info('issue %r' % text)
if 'pull' in name.lower():
category = 'pull'
elif 'issue' in name.lower():
@@ -105,7 +104,6 @@ def ghuser_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
:param content: The directive content for customization.
"""
app = inliner.document.settings.env.app
- #app.info('user link %r' % text)
ref = 'https://www.github.com/' + text
node = nodes.reference(rawtext, text, refuri=ref, **options)
return [node], []
@@ -126,7 +124,6 @@ def ghcommit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
:param content: The directive content for customization.
"""
app = inliner.document.settings.env.app
- #app.info('user link %r' % text)
try:
base = app.config.github_project_url
if not base:
@@ -146,7 +143,6 @@ def setup(app):
:param app: Sphinx application context.
"""
- app.info('Initializing GitHub plugin')
app.add_role('ghissue', ghissue_role)
app.add_role('ghpull', ghissue_role)
app.add_role('ghuser', ghuser_role)
diff --git a/doc/users/next_whats_new/2018-09-06-AL.rst b/doc/users/next_whats_new/2018-09-06-AL.rst
deleted file mode 100644
index dc0ca84f3252..000000000000
--- a/doc/users/next_whats_new/2018-09-06-AL.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-:orphan:
-
-Return type of ArtistInspector.get_aliases changed
-``````````````````````````````````````````````````
-
-`ArtistInspector.get_aliases` previously returned the set of aliases as
-``{fullname: {alias1: None, alias2: None, ...}}``. The dict-to-None mapping
-was used to simulate a set in earlier versions of Python. It has now been
-replaced by a set, i.e. ``{fullname: {alias1, alias2, ...}}``.
-
-This value is also stored in `ArtistInspector.aliasd`, which has likewise
-changed.
diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst
index 4f89851070b5..2c130030dded 100644
--- a/doc/users/whats_new.rst
+++ b/doc/users/whats_new.rst
@@ -239,6 +239,29 @@ Headless linux servers (identified by the DISPLAY env not being defined)
will not select a GUI backend.
+Return type of ArtistInspector.get_aliases changed
+``````````````````````````````````````````````````
+
+`ArtistInspector.get_aliases` previously returned the set of aliases as
+``{fullname: {alias1: None, alias2: None, ...}}``. The dict-to-None mapping
+was used to simulate a set in earlier versions of Python. It has now been
+replaced by a set, i.e. ``{fullname: {alias1, alias2, ...}}``.
+
+This value is also stored in `ArtistInspector.aliasd`, which has likewise
+changed.
+
+
+``:math:`` directive renamed to ``:mathmpl:``
+`````````````````````````````````````````````
+
+The ``:math:`` rst role provided by `matplotlib.sphinxext.mathmpl` has been
+renamed to ``:mathmpl:`` to avoid conflicting with the ``:math:`` role that
+Sphinx 1.8 provides by default. (``:mathmpl:`` uses Matplotlib to render math
+expressions to images embedded in html, whereas Sphinx uses MathJax.)
+
+When using Sphinx<1.8, both names (``:math:`` and ``:mathmpl:``) remain
+available for backcompatibility.
+
==================
Previous Whats New
diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py
index a198cb5fe66c..3df090452a02 100644
--- a/lib/matplotlib/colorbar.py
+++ b/lib/matplotlib/colorbar.py
@@ -267,7 +267,8 @@ def __call__(self):
vmin = self._colorbar.norm.vmin
vmax = self._colorbar.norm.vmax
ticks = ticker.AutoMinorLocator.__call__(self)
- return ticks[(ticks >= vmin) & (ticks <= vmax)]
+ rtol = (vmax - vmin) * 1e-10
+ return ticks[(ticks >= vmin - rtol) & (ticks <= vmax + rtol)]
class _ColorbarLogLocator(ticker.LogLocator):
diff --git a/lib/matplotlib/sphinxext/mathmpl.py b/lib/matplotlib/sphinxext/mathmpl.py
index aef2fb877bb9..b1b934304a76 100644
--- a/lib/matplotlib/sphinxext/mathmpl.py
+++ b/lib/matplotlib/sphinxext/mathmpl.py
@@ -1,10 +1,11 @@
+import hashlib
import os
import sys
-from hashlib import md5
+import warnings
from docutils import nodes
from docutils.parsers.rst import directives
-import warnings
+import sphinx
from matplotlib import rcParams
from matplotlib.mathtext import MathTextParser
@@ -61,7 +62,7 @@ def latex2png(latex, filename, fontset='cm'):
def latex2html(node, source):
inline = isinstance(node.parent, nodes.TextElement)
latex = node['latex']
- name = 'math-%s' % md5(latex.encode()).hexdigest()[-10:]
+ name = 'math-%s' % hashlib.md5(latex.encode()).hexdigest()[-10:]
destdir = os.path.join(setup.app.builder.outdir, '_images', 'mathmpl')
if not os.path.exists(destdir):
@@ -110,9 +111,13 @@ def depart_latex_math_latex(self, node):
app.add_node(latex_math,
html=(visit_latex_math_html, depart_latex_math_html),
latex=(visit_latex_math_latex, depart_latex_math_latex))
- app.add_role('math', math_role)
- app.add_directive('math', math_directive,
+ app.add_role('mathmpl', math_role)
+ app.add_directive('mathmpl', math_directive,
True, (0, 0, 0), **options_spec)
+ if sphinx.version_info < (1, 8):
+ app.add_role('math', math_role)
+ app.add_directive('math', math_directive,
+ True, (0, 0, 0), **options_spec)
metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
return metadata
diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py
index 2230c20e7d2f..56a829418910 100644
--- a/lib/matplotlib/tests/test_colorbar.py
+++ b/lib/matplotlib/tests/test_colorbar.py
@@ -294,6 +294,15 @@ def test_colorbar_minorticks_on_off():
np.testing.assert_almost_equal(cbar.ax.yaxis.get_minorticklocs(),
np.array([]))
+ im.set_clim(vmin=-1.2, vmax=1.2)
+ cbar.minorticks_on()
+ correct_minorticklocs = np.array([-1.2, -1.1, -0.9, -0.8, -0.7, -0.6,
+ -0.4, -0.3, -0.2, -0.1, 0.1, 0.2,
+ 0.3, 0.4, 0.6, 0.7, 0.8, 0.9,
+ 1.1, 1.2])
+ np.testing.assert_almost_equal(cbar.ax.yaxis.get_minorticklocs(),
+ correct_minorticklocs)
+
def test_colorbar_autoticks():
# Test new autotick modes. Needs to be classic because
diff --git a/setup.cfg.template b/setup.cfg.template
index 7ccfb7edcbe4..4fed27d31302 100644
--- a/setup.cfg.template
+++ b/setup.cfg.template
@@ -63,15 +63,9 @@
# behavior
#
#agg = auto
-#cairo = auto
-#gtk3agg = auto
-#gtk3cairo = auto
#macosx = auto
-#pyside = auto
-#qt4agg = auto
#tkagg = auto
#windowing = auto
-#wxagg = auto
[rc_options]
# User-configurable options
@@ -81,10 +75,9 @@
#
# The Agg, Ps, Pdf and SVG backends do not require external dependencies. Do
# not choose MacOSX, or TkAgg if you have disabled the relevant extension
-# modules. Agg will be used by default.
+# modules. The default is determined by fallback.
#
#backend = Agg
-#
[package_data]
# Package additional files found in the lib/matplotlib directories.
diff --git a/setup.py b/setup.py
index 6eab9b6b88fd..7e82e94c29c8 100644
--- a/setup.py
+++ b/setup.py
@@ -70,18 +70,9 @@
setupext.Tests(),
setupext.Toolkits_Tests(),
'Optional backend extensions',
- # These backends are listed in order of preference, the first
- # being the most preferred. The first one that looks like it will
- # work will be selected as the default backend.
- setupext.BackendMacOSX(),
- setupext.BackendQt5(),
- setupext.BackendQt4(),
- setupext.BackendGtk3Agg(),
- setupext.BackendGtk3Cairo(),
- setupext.BackendTkAgg(),
- setupext.BackendWxAgg(),
setupext.BackendAgg(),
- setupext.BackendCairo(),
+ setupext.BackendTkAgg(),
+ setupext.BackendMacOSX(),
setupext.Windowing(),
'Optional package data',
setupext.Dlls(),
@@ -133,7 +124,6 @@ def run(self):
package_dir = {'': 'lib'}
install_requires = []
setup_requires = []
- default_backend = None
# If the user just queries for information, don't bother figuring out which
# packages to build or install.
@@ -169,10 +159,6 @@ def run(self):
required_failed.append(package)
else:
good_packages.append(package)
- if (isinstance(package, setupext.OptionalBackendPackage)
- and package.runtime_check()
- and default_backend is None):
- default_backend = package.name
print_raw('')
# Abort if any of the required packages can not be built.
@@ -203,14 +189,16 @@ def run(self):
setup_requires.extend(package.get_setup_requires())
# Write the default matplotlibrc file
- if default_backend is None:
- default_backend = 'svg'
- if setupext.options['backend']:
- default_backend = setupext.options['backend']
with open('matplotlibrc.template') as fd:
- template = fd.read()
+ template_lines = fd.read().splitlines(True)
+ backend_line_idx, = [ # Also asserts that there is a single such line.
+ idx for idx, line in enumerate(template_lines)
+ if line.startswith('#backend ')]
+ if setupext.options['backend']:
+ template_lines[backend_line_idx] = (
+ 'backend: {}'.format(setupext.options['backend']))
with open('lib/matplotlib/mpl-data/matplotlibrc', 'w') as fd:
- fd.write(template)
+ fd.write(''.join(template_lines))
# Finalize the extension modules so they can get the Numpy include
# dirs
diff --git a/setupext.py b/setupext.py
index 5644bae9dab5..582c7d89c9da 100644
--- a/setupext.py
+++ b/setupext.py
@@ -384,13 +384,6 @@ def check(self):
"""
pass
- def runtime_check(self):
- """
- True if the runtime dependencies of the backend are met. Assumes that
- the build-time dependencies are met.
- """
- return True
-
def get_packages(self):
"""
Get a list of package names to add to the configuration.
@@ -1368,10 +1361,6 @@ class BackendTkAgg(OptionalBackendPackage):
def check(self):
return "installing; run-time loading from Python Tcl / Tk"
- def runtime_check(self):
- """Checks whether TkAgg runtime dependencies are met."""
- return importlib.util.find_spec("tkinter") is not None
-
def get_extension(self):
sources = [
'src/_tkagg.cpp'
@@ -1391,57 +1380,6 @@ def add_flags(self, ext):
ext.libraries.extend(['dl'])
-class BackendGtk3Agg(OptionalBackendPackage):
- name = "gtk3agg"
-
- def check_requirements(self):
- if not any(map(importlib.util.find_spec, ["cairocffi", "cairo"])):
- raise CheckFailed("Requires cairocffi or pycairo to be installed.")
-
- try:
- import gi
- except ImportError:
- raise CheckFailed("Requires pygobject to be installed.")
-
- try:
- gi.require_version("Gtk", "3.0")
- except ValueError:
- raise CheckFailed(
- "Requires gtk3 development files to be installed.")
- except AttributeError:
- raise CheckFailed("pygobject version too old.")
-
- try:
- from gi.repository import Gtk, Gdk, GObject
- except (ImportError, RuntimeError):
- raise CheckFailed("Requires pygobject to be installed.")
-
- return "version {}.{}.{}".format(
- Gtk.get_major_version(),
- Gtk.get_minor_version(),
- Gtk.get_micro_version())
-
- def get_package_data(self):
- return {'matplotlib': ['mpl-data/*.glade']}
-
-
-class BackendGtk3Cairo(BackendGtk3Agg):
- name = "gtk3cairo"
-
-
-class BackendWxAgg(OptionalBackendPackage):
- name = "wxagg"
-
- def check_requirements(self):
- try:
- import wx
- backend_version = wx.VERSION_STRING
- except ImportError:
- raise CheckFailed("requires wxPython")
-
- return "version %s" % backend_version
-
-
class BackendMacOSX(OptionalBackendPackage):
name = 'macosx'
@@ -1487,174 +1425,6 @@ def get_extension(self):
return ext
-class BackendQtBase(OptionalBackendPackage):
-
- def convert_qt_version(self, version):
- version = '%x' % version
- temp = []
- while len(version) > 0:
- version, chunk = version[:-2], version[-2:]
- temp.insert(0, str(int(chunk, 16)))
- return '.'.join(temp)
-
- def check_requirements(self):
- """
- If PyQt4/PyQt5 is already imported, importing PyQt5/PyQt4 will fail
- so we need to test in a subprocess (as for Gtk3).
- """
- try:
- p = multiprocessing.Pool()
-
- except:
- # Can't do multiprocessing, fall back to normal approach
- # (this will fail if importing both PyQt4 and PyQt5).
- try:
- # Try in-process
- msg = self.callback(self)
- except RuntimeError:
- raise CheckFailed(
- "Could not import: are PyQt4 & PyQt5 both installed?")
-
- else:
- # Multiprocessing OK
- try:
- res = p.map_async(self.callback, [self])
- msg = res.get(timeout=10)[0]
- except multiprocessing.TimeoutError:
- p.terminate()
- # No result returned. Probably hanging, terminate the process.
- raise CheckFailed("Check timed out")
- except:
- # Some other error.
- p.close()
- raise
- else:
- # Clean exit
- p.close()
- finally:
- # Tidy up multiprocessing
- p.join()
-
- return msg
-
-
-def backend_pyside_internal_check(self):
- try:
- from PySide import __version__
- from PySide import QtCore
- except ImportError:
- raise CheckFailed("PySide not found")
- else:
- return ("Qt: %s, PySide: %s" %
- (QtCore.__version__, __version__))
-
-
-def backend_pyqt4_internal_check(self):
- try:
- from PyQt4 import QtCore
- except ImportError:
- raise CheckFailed("PyQt4 not found")
-
- try:
- qt_version = QtCore.QT_VERSION
- pyqt_version_str = QtCore.PYQT_VERSION_STR
- except AttributeError:
- raise CheckFailed('PyQt4 not correctly imported')
- else:
- return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str))
-
-
-def backend_qt4_internal_check(self):
- successes = []
- failures = []
- try:
- successes.append(backend_pyside_internal_check(self))
- except CheckFailed as e:
- failures.append(str(e))
-
- try:
- successes.append(backend_pyqt4_internal_check(self))
- except CheckFailed as e:
- failures.append(str(e))
-
- if len(successes) == 0:
- raise CheckFailed('; '.join(failures))
- return '; '.join(successes + failures)
-
-
-class BackendQt4(BackendQtBase):
- name = "qt4agg"
-
- def __init__(self, *args, **kwargs):
- BackendQtBase.__init__(self, *args, **kwargs)
- self.callback = backend_qt4_internal_check
-
-def backend_pyside2_internal_check(self):
- try:
- from PySide2 import __version__
- from PySide2 import QtCore
- except ImportError:
- raise CheckFailed("PySide2 not found")
- else:
- return ("Qt: %s, PySide2: %s" %
- (QtCore.__version__, __version__))
-
-def backend_pyqt5_internal_check(self):
- try:
- from PyQt5 import QtCore
- except ImportError:
- raise CheckFailed("PyQt5 not found")
-
- try:
- qt_version = QtCore.QT_VERSION
- pyqt_version_str = QtCore.PYQT_VERSION_STR
- except AttributeError:
- raise CheckFailed('PyQt5 not correctly imported')
- else:
- return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str))
-
-def backend_qt5_internal_check(self):
- successes = []
- failures = []
- try:
- successes.append(backend_pyside2_internal_check(self))
- except CheckFailed as e:
- failures.append(str(e))
-
- try:
- successes.append(backend_pyqt5_internal_check(self))
- except CheckFailed as e:
- failures.append(str(e))
-
- if len(successes) == 0:
- raise CheckFailed('; '.join(failures))
- return '; '.join(successes + failures)
-
-class BackendQt5(BackendQtBase):
- name = "qt5agg"
-
- def __init__(self, *args, **kwargs):
- BackendQtBase.__init__(self, *args, **kwargs)
- self.callback = backend_qt5_internal_check
-
-
-class BackendCairo(OptionalBackendPackage):
- name = "cairo"
-
- def check_requirements(self):
- try:
- import cairocffi
- except ImportError:
- try:
- import cairo
- except ImportError:
- raise CheckFailed("cairocffi or pycairo not found")
- else:
- return "pycairo version %s" % cairo.version
- else:
- return "cairocffi version %s" % cairocffi.version
-
-
class OptionalPackageData(OptionalPackage):
config_category = "package_data"
diff --git a/tutorials/text/mathtext.py b/tutorials/text/mathtext.py
index 9fafdcf1ed64..4ed6e297c73e 100644
--- a/tutorials/text/mathtext.py
+++ b/tutorials/text/mathtext.py
@@ -44,7 +44,7 @@
# # math text
# plt.title(r'$\alpha > \beta$')
#
-# produces ":math:`\alpha > \beta`".
+# produces ":mathmpl:`\alpha > \beta`".
#
# .. note::
# Mathtext should be placed between a pair of dollar signs ($). To
@@ -77,9 +77,9 @@
#
# \alpha_i > \beta_i
#
-# Some symbols automatically put their sub/superscripts under and over
-# the operator. For example, to write the sum of :math:`x_i` from :math:`0` to
-# :math:`\infty`, you could do::
+# Some symbols automatically put their sub/superscripts under and over the
+# operator. For example, to write the sum of :mathmpl:`x_i` from :mathmpl:`0`
+# to :mathmpl:`\infty`, you could do::
#
# r'$\sum_{i=0}^\infty x_i$'
#
@@ -200,13 +200,13 @@
# ============================ ==================================
# Command Result
# ============================ ==================================
-# ``\mathrm{Roman}`` :math:`\mathrm{Roman}`
-# ``\mathit{Italic}`` :math:`\mathit{Italic}`
-# ``\mathtt{Typewriter}`` :math:`\mathtt{Typewriter}`
-# ``\mathcal{CALLIGRAPHY}`` :math:`\mathcal{CALLIGRAPHY}`
+# ``\mathrm{Roman}`` :mathmpl:`\mathrm{Roman}`
+# ``\mathit{Italic}`` :mathmpl:`\mathit{Italic}`
+# ``\mathtt{Typewriter}`` :mathmpl:`\mathtt{Typewriter}`
+# ``\mathcal{CALLIGRAPHY}`` :mathmpl:`\mathcal{CALLIGRAPHY}`
# ============================ ==================================
#
-# .. role:: math-stix(math)
+# .. role:: math-stix(mathmpl)
# :fontset: stix
#
# When using the `STIX
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: