8000 Merge pull request #22567 from ianthomas23/use_contourpy · matplotlib/matplotlib@52b122e · GitHub
[go: up one dir, main page]

Skip to content

Commit 52b122e

Browse files
authored
Merge pull request #22567 from ianthomas23/use_contourpy
Use contourpy for quad contour calculations
2 parents a4f62d4 + 57b167e commit 52b122e

File tree

19 files changed

+372
-2842
lines changed

19 files changed

+372
-2842
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ jobs:
161161
162162
# Install dependencies from PyPI.
163163
python -m pip install --upgrade $PRE \
164-
cycler fonttools kiwisolver numpy packaging pillow pyparsing \
164+
contourpy>=1.0.1 cycler fonttools kiwisolver numpy packaging pillow pyparsing \
165165
python-dateutil setuptools-scm \
166166
-r requirements/testing/all.txt \
167167
${{ matrix.extra-requirements }}

doc/api/next_api_changes/behavior/22229-TAC.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
AritistList proxies copy contents on iteration
2-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1+
ArtistList proxies copy contents on iteration
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33

44
When iterating over the contents of the the dynamically generated proxy lists
55
for the Artist-type accessors (see :ref:`Behavioural API Changes 3.5 - Axes
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
New algorithm keyword argument to contour and contourf
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The contouring functions `~matplotlib.axes.Axes.contour` and
5+
`~matplotlib.axes.Axes.contourf` have a new keyword argument *algorithm* to
6+
control which algorithm is used to calculate the contours. There is a choice
7+
of four algorithms to use, and the default is to use ``algorithm='mpl2014'``
8+
which is the same algorithm that Matplotlib has been using since 2014.
9+
10+
Other possible values of the *algorithm* keyword argument are ``'mpl2005'``,
11+
``'serial'`` and ``'threaded'``; see the
12+
`ContourPy documentation <https://contourpy.readthedocs.io>`_ for further
13+
details.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
New external dependency ContourPy used for quad contour calculations
2+
--------------------------------------------------------------------
3+
4+
Previously Matplotlib shipped its own C++ code for calculating the contours of
5+
quad grids. Now the external library
6+
`ContourPy <https://github.com/contourpy/contourpy>`_ is used instead. There
7+
is a choice of four algorithms to use, controlled by the *algorithm* keyword
8+
argument to the functions `~matplotlib.axes.Axes.contour` and
9+
`~matplotlib.axes.Axes.contourf`. The default behaviour is to use
10+
``algorithm='mpl2014'`` which is the same algorithm that Matplotlib has been
11+
using since 2014.
12+
13+
See the `ContourPy documentation <https://contourpy.readthedocs.io>`_ for
14+
further details of the different algorithms.
15+
16+
.. note::
17+
18+
Contour lines and polygons produced by ``algorithm='mpl2014'`` will be the
19+
same as those produced before this change to within floating-point
20+
tolerance. The exception is for duplicate points, i.e. contours containing
21+
adjacent (x, y) points that are identical; previously the duplicate points
22+
were removed, now they are kept. Contours affected by this will produce the
23+
same visual output, but there will be a greater number of points in the
24+
contours.
25+
26+
The locations of contour labels obtained by using
27+
`~matplotlib.axes.Axes.clabel` may also be different.

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ channels:
99
- conda-forge
1010
dependencies:
1111
- cairocffi
12+
- contourpy>=1.0.1
1213
- cycler>=0.10.0
1314
- fonttools>=4.22.0
1415
- kiwisolver>=1.0.1

lib/matplotlib/contour.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@ class QuadContourSet(ContourSet):
14201420
%(contour_set_attributes)s
14211421
"""
14221422

1423-
def _process_args(self, *args, corner_mask=None, **kwargs):
1423+
def _process_args(self, *args, corner_mask=None, algorithm=None, **kwargs):
14241424
"""
14251425
Process args and kwargs.
14261426
"""
@@ -1433,21 +1433,31 @@ def _process_args(self, *args, corner_mask=None, **kwargs):
14331433
contour_generator = args[0]._contour_generator
14341434
self._mins = args[0]._mins
14351435
self._maxs = args[0]._maxs
1436+
self._algorithm = args[0]._algorithm
14361437
else:
1437-
import matplotlib._contour as _contour
1438+
import contourpy
1439+
1440+
if algorithm is None:
1441+
algorithm = mpl.rcParams['contour.algorithm']
1442+
mpl.rcParams.validate["contour.algorithm"](algorithm)
1443+
self._algorithm = algorithm
14381444

14391445
if corner_mask is None:
1440-
corner_mask = mpl.rcParams['contour.corner_mask']
1446+
if self._algorithm == "mpl2005":
1447+
# mpl2005 does not support corner_mask=True so if not
1448+
# specifically requested then disable it.
1449+
corner_mask = False
1450+
else:
1451+
corner_mask = mpl.rcParams['contour.corner_mask']
14411452
self._corner_mask = corner_mask
14421453

14431454
x, y, z = self._contour_args(args, kwargs)
14441455

1445-
_mask = ma.getmask(z)
1446-
if _mask is ma.nomask or not _mask.any():
1447-
_mask = None
1448-
1449-
contour_generator = _contour.QuadContourGenerator(
1450-
x, y, z.filled(), _mask, self._corner_mask, self.nchunk)
1456+
contour_generator = contourpy.contour_generator(
1457+
x, y, z, name=self._algorithm, corner_mask=self._corner_mask,
1458+
line_type=contourpy.LineType.SeparateCode,
1459+
fill_type=contourpy.FillType.OuterCode,
1460+
chunk_size=self.nchunk)
14511461

14521462
t = self.get_transform()
14531463

@@ -1772,6 +1782,15 @@ def _initialize_x_y(self, z):
17721782
Hatching is supported in the PostScript, PDF, SVG and Agg
17731783
backends only.
17741784
1785+
algorithm : {'mpl2005', 'mpl2014', 'serial', 'threaded'}, optional
1786+
Which contouring algorithm to use to calculate the contour lines and
1787+
polygons. The algorithms are implemented in
1788+
`ContourPy <https://github.com/contourpy/contourpy>`_, consult the
1789+
`ContourPy documentation <https://contourpy.readthedocs.io>`_ for
1790+
further information.
1791+
1792+
The default is taken from :rc:`contour.algorithm`.
1793+
17751794
data : indexable object, optional
17761795
DATA_PARAMETER_PLACEHOLDER
17771796
@@ -1792,5 +1811,5 @@ def _initialize_x_y(self, z):
17921811
3. `.contour` and `.contourf` use a `marching squares
17931812
<https://en.wikipedia.org/wiki/Marching_squares>`_ algorithm to
17941813
compute contour locations. More information can be found in
1795-
the source ``src/_contour.h``.
1814+
`ContourPy documentation <https://contourpy.readthedocs.io>`_.
17961815
""")

lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,10 +607,11 @@
607607
## * CONTOUR PLOTS *
608608
## ***************************************************************************
609609
#contour.negative_linestyle: dashed # string or on-off ink sequence
610-
#contour.corner_mask: True # {True, False, legacy}
610+
#contour.corner_mask: True # {True, False}
611611
#contour.linewidth: None # {float, None} Size of the contour line
612612
# widths. If set to None, it falls back to
613613
# `line.linewidth`.
614+
#contour.algorithm: mpl2014 # {mpl2005, mpl2014, serial, threaded}
614615

615616

616617
## ***************************************************************************

lib/matplotlib/rcsetup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ def _convert_validator_spec(key, conv):
960960
"contour.negative_linestyle": _validate_linestyle,
961961
"contour.corner_mask": validate_bool,
962962
"contour.linewidth": validate_float_or_None,
963+
"contour.algorithm": ["mpl2005", "mpl2014", "serial", "threaded"],
963964

964965
# errorbar props
965966
"errorbar.capsize": validate_float,
Loading
Binary file not shown.
Loading

0 commit comments

Comments
 (0)
0