Skip to content

Commit a500e3b

Browse files
authored
Merge branch 'matplotlib:main' into jaco-doc-update
2 parents 93de607 + 42fdbea commit a500e3b

35 files changed

Lines changed: 3259 additions & 3143 deletions

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ per-file-ignores =
6060
lib/matplotlib/pyplot.py: F401, F811
6161
lib/matplotlib/tests/test_mathtext.py: E501
6262
lib/matplotlib/transforms.py: E201, E202, E203
63-
lib/matplotlib/tri/triinterpolate.py: E201, E221
63+
lib/matplotlib/tri/_triinterpolate.py: E201, E221
6464
lib/mpl_toolkits/axes_grid1/axes_size.py: E272
6565
lib/mpl_toolkits/axisartist/__init__.py: F401
6666
lib/mpl_toolkits/axisartist/angle_helper.py: E221

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
- [ ] Is [Flake 8](https://flake8.pycqa.org/en/latest/) compliant (install `flake8-docstrings` and run `flake8 --docstring-convention=all`).
99

1010
**Documentation**
11-
- [ ] New features are documented, with examples if plot related.
12-
- [ ] New features have an entry in `doc/users/next_whats_new/` (follow instructions in README.rst there).
13-
- [ ] API changes documented in `doc/api/next_api_changes/` (follow instructions in README.rst there).
1411
- [ ] Documentation is sphinx and numpydoc compliant (the docs should [build](https://matplotlib.org/devel/documenting_mpl.html#building-the-docs) without error).
12+
- [ ] New plotting related features are documented with examples.
13+
14+
**Release Notes**
15+
- [ ] New features are marked with a `.. versionadded::` directive in the docstring and documented in `doc/users/next_whats_new/`
16+
- [ ] API changes are marked with a `.. versionchanged::` directive in the docstring and documented in `doc/api/next_api_changes/`
17+
- [ ] Release notes conform with instructions in `next_whats_new/README.rst` or `next_api_changes/README.rst`
1518

1619
<!--
1720
Thank you so much for your PR! To help us review your contribution, please
@@ -22,7 +25,7 @@ consider the following points:
2225
- Help with git and github is available at
2326
https://matplotlib.org/devel/gitwash/development_workflow.html.
2427
25-
- Do not create the PR out of main, but out of a separate branch.
28+
- Create a separate branch for your changes and open the PR from this branch. Please avoid working on `main`.
2629
2730
- The PR title should summarize the changes, for example "Raise ValueError on
2831
non-numeric input to set_xlim". Avoid non-descriptive titles such as
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``matplotlib.tri`` submodules are deprecated
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The ``matplotlib.tri.*`` submodules are deprecated. All functionality is
5+
available in ``matplotlib.tri`` directly and should be imported from there.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``parse_fontconfig_pattern`` will no longer ignore unknown constant names
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Previously, in a fontconfig pattern like ``DejaVu Sans:foo``, the unknown
4+
``foo`` constant name would be silently ignored. This now raises a warning,
5+
and will become an error in the future.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
``auto_add_to_figure=True`` for ``Axes3D``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
... is no longer supported. Instead use ``fig.add_axes(ax)``.

doc/devel/coding_guide.rst

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,60 @@ Documentation
108108

109109
* See :ref:`documenting-matplotlib` for our documentation style guide.
110110

111-
* If your change is a major new feature, add an entry to
112-
:file:`doc/users/whats_new.rst`.
111+
.. _release_notes:
113112

114-
* If you change the API in a backward-incompatible way, please
115-
document it by adding a file in the relevant subdirectory of
116-
:file:`doc/api/next_api_changes/`, probably in the ``behavior/``
117-
subdirectory.
113+
New features and API changes
114+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
115+
When adding a major new feature or changing the API in a backward incompatible
116+
way, please document it by including a versioning directive in the docstring
117+
and adding an entry to the folder for either the what's new or API change notes.
118+
119+
+-------------------+-----------------------------+----------------------------------+
120+
| for this addition | include this directive | create entry in this folder |
121+
+===================+=============================+==================================+
122+
| new feature | ``.. versionadded:: 3.N`` | :file:`doc/users/next_whats_new/`|
123+
+-------------------+-----------------------------+----------------------------------+
124+
| API change | ``.. versionchanged:: 3.N`` | :file:`doc/api/next_api_changes/`|
125+
| | | |
126+
| | | probably in ``behavior/`` |
127+
+-------------------+-----------------------------+----------------------------------+
128+
129+
The directives should be placed at the end of a description block. For example::
130+
131+
class Foo:
132+
"""
133+
This is the summary.
134+
135+
Followed by a longer description block.
136+
137+
Consisting of multiple lines and paragraphs.
138+
139+
.. versionadded:: 3.5
140+
141+
Parameters
142+
----------
143+
a : int
144+
The first parameter.
145+
b: bool, default: False
146+
This was added later.
147+
148+
.. versionadded:: 3.6
149+
"""
150+
151+
def set_b(b):
152+
"""
153+
Set b.
154+
155+
.. versionadded:: 3.6
156+
157+
Parameters
158+
----------
159+
b: bool
160+
161+
For classes and functions, the directive should be placed before the
162+
*Parameters* section. For parameters, the directive should be placed at the
163+
end of the parameter description. The patch release version is omitted and
164+
the directive should not be added to entire modules.
118165

119166
.. _pr-labels:
120167

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
rcParam for 3D pane color
2+
-------------------------
3+
4+
The rcParams :rc:`axes3d.xaxis.panecolor`, :rc:`axes3d.yaxis.panecolor`,
5+
:rc:`axes3d.zaxis.panecolor` can be used to change the color of the background
6+
panes in 3D plots. Note that it is often beneficial to give them slightly
7+
different shades to obtain a "3D effect" and to make them slightly transparent
8+
(alpha < 1).
9+
10+
.. plot::
11+
:include-source: true
12+
13+
import matplotlib.pyplot as plt
14+
with plt.rc_context({'axes3d.xaxis.panecolor': (0.9, 0.0, 0.0, 0.5),
15+
'axes3d.yaxis.panecolor': (0.7, 0.0, 0.0, 0.5),
16+
'axes3d.zaxis.panecolor': (0.8, 0.0, 0.0, 0.5)}):
17+
fig = plt.figure()
18+
fig.add_subplot(projection='3d')

lib/matplotlib/_fontconfig_pattern.py

Lines changed: 45 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,29 @@
99
# there would have created cyclical dependency problems, because it also needs
1010
# to be available from `matplotlib.rcsetup` (for parsing matplotlibrc files).
1111

12-
from functools import lru_cache
12+
from functools import lru_cache, partial
1313
import re
1414

1515
import numpy as np
1616
from pyparsing import (
17-
Literal, Optional, ParseException, Regex, StringEnd, Suppress, ZeroOrMore,
18-
)
17+
Optional, ParseException, Regex, StringEnd, Suppress, ZeroOrMore)
18+
19+
from matplotlib import _api
20+
1921

2022
family_punc = r'\\\-:,'
21-
family_unescape = re.compile(r'\\([%s])' % family_punc).sub
23+
_family_unescape = partial(re.compile(r'\\(?=[%s])' % family_punc).sub, '')
2224
family_escape = re.compile(r'([%s])' % family_punc).sub
2325

2426
value_punc = r'\\=_:,'
25-
value_unescape = re.compile(r'\\([%s])' % value_punc).sub
27+
_value_unescape = partial(re.compile(r'\\(?=[%s])' % value_punc).sub, '')
2628
value_escape = re.compile(r'([%s])' % value_punc).sub
2729

30+
# Remove after module deprecation elapses (3.8); then remove underscores
31+
# from _family_unescape and _value_unescape.
32+
family_unescape = re.compile(r'\\([%s])' % family_punc).sub
33+
value_unescape = re.compile(r'\\([%s])' % value_punc).sub
34+
2835

2936
class FontconfigPatternParser:
3037
"""
@@ -58,63 +65,27 @@ class FontconfigPatternParser:
5865
'semicondensed': ('width', 'semi-condensed'),
5966
'expanded': ('width', 'expanded'),
6067
'extraexpanded': ('width', 'extra-expanded'),
61-
'ultraexpanded': ('width', 'ultra-expanded')
62-
}
68+
'ultraexpanded': ('width', 'ultra-expanded'),
69+
}
6370

6471
def __init__(self):
65-
66-
family = Regex(
67-
r'([^%s]|(\\[%s]))*' % (family_punc, family_punc)
68-
).setParseAction(self._family)
69-
70-
size = Regex(
71-
r"([0-9]+\.?[0-9]*|\.[0-9]+)"
72-
).setParseAction(self._size)
73-
74-
name = Regex(
75-
r'[a-z]+'
76-
).setParseAction(self._name)
77-
78-
value = Regex(
79-
r'([^%s]|(\\[%s]))*' % (value_punc, value_punc)
80-
).setParseAction(self._value)
81-
82-
families = (
83-
family
84-
+ ZeroOrMore(
85-
Literal(',')
86-
+ family)
87-
).setParseAction(self._families)
88-
89-
point_sizes = (
90-
size
91-
+ ZeroOrMore(
92-
Literal(',')
93-
+ size)
94-
).setParseAction(self._point_sizes)
95-
96-
property = (
97-
(name
98-
+ Suppress(Literal('='))
99-
+ value
100-
+ ZeroOrMore(
101-
Suppress(Literal(','))
102-
+ value))
103-
| name
104-
).setParseAction(self._property)
105-
72+
def comma_separated(elem):
73+
return elem + ZeroOrMore(Suppress(",") + elem)
74+
75+
family = Regex(r"([^%s]|(\\[%s]))*" % (family_punc, family_punc))
76+
size = Regex(r"([0-9]+\.?[0-9]*|\.[0-9]+)")
77+
name = Regex(r"[a-z]+")
78+
value = Regex(r"([^%s]|(\\[%s]))*" % (value_punc, value_punc))
79+
prop = (
80+
(name + Suppress("=") + comma_separated(value))
81+
| name # replace by oneOf(self._constants) in mpl 3.9.
82+
)
10683
pattern = (
107-
Optional(
108-
families)
109-
+ Optional(
110-
Literal('-')
111-
+ point_sizes)
112-
+ ZeroOrMore(
113-
Literal(':')
114-
+ property)
84+
Optional(comma_separated(family)("families"))
85+
+ Optional("-" + comma_separated(size)("sizes"))
86+
+ ZeroOrMore(":" + prop("properties*"))
11587
+ StringEnd()
11688
)
117-
11889
self._parser = pattern
11990
self.ParseException = ParseException
12091

@@ -124,47 +95,30 @@ def parse(self, pattern):
12495
of key/value pairs useful for initializing a
12596
`.font_manager.FontProperties` object.
12697
"""
127-
props = self._properties = {}
12898
try:
129-
self._parser.parseString(pattern)
99+
parse = self._parser.parseString(pattern)
130100
except ParseException as err:
131101
# explain becomes a plain method on pyparsing 3 (err.explain(0)).
132102
raise ValueError("\n" + ParseException.explain(err, 0)) from None
133-
self._properties = None
134103
self._parser.resetCache()
104+
props = {}
105+
if "families" in parse:
106+
props["family"] = [*map(_family_unescape, parse["families"])]
107+
if "sizes" in parse:
108+
props["size"] = [*parse["sizes"]]
109+
for prop in parse.get("properties", []):
110+
if len(prop) == 1:
111+
if prop[0] not in self._constants:
112+
_api.warn_deprecated(
113+
"3.7", message=f"Support for unknown constants "
114+
f"({prop[0]!r}) is deprecated since %(since)s and "
115+
f"will be removed %(removal)s.")
116+
continue
117+
prop = self._constants[prop[0]]
118+
k, *v = prop
119+
props.setdefault(k, []).extend(map(_value_unescape, v))
135120
return props
136121

137-
def _family(self, s, loc, tokens):
138-
return [family_unescape(r'\1', str(tokens[0]))]
139-
140-
def _size(self, s, loc, tokens):
141-
return [float(tokens[0])]
142-
143-
def _name(self, s, loc, tokens):
144-
return [str(tokens[0])]
145-
146-
def _value(self, s, loc, tokens):
147-
return [value_unescape(r'\1', str(tokens[0]))]
148-
149-
def _families(self, s, loc, tokens):
150-
self._properties['family'] = [str(x) for x in tokens]
151-
return []
152-
153-
def _point_sizes(self, s, loc, tokens):
154-
self._properties['size'] = [str(x) for x in tokens]
155-
return []
156-
157-
def _property(self, s, loc, tokens):
158-
if len(tokens) == 1:
159-
if tokens[0] in self._constants:
160-
key, val = self._constants[tokens[0]]
161-
self._properties.setdefault(key, []).append(val)
162-
else:
163-
key = tokens[0]
164-
val = tokens[1:]
165-
self._properties.setdefault(key, []).extend(val)
166-
return []
167-
168122

169123
# `parse_fontconfig_pattern` is a bottleneck during the tests because it is
170124
# repeatedly called when the rcParams are reset (to validate the default

lib/matplotlib/figure.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,8 +1679,6 @@ def _process_projection_requirements(
16791679
raise TypeError(
16801680
f"projection must be a string, None or implement a "
16811681
f"_as_mpl_axes method, not {projection!r}")
1682-
if projection_class.__name__ == 'Axes3D':
1683-
kwargs.setdefault('auto_add_to_figure', False)
16841682
return projection_class, kwargs
16851683

16861684
def get_default_bbox_extra_artists(self):

lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,9 @@
427427
#polaraxes.grid: True # display grid on polar axes
428428
#axes3d.grid: True # display grid on 3D axes
429429

430+
#axes3d.xaxis.panecolor: (0.95, 0.95, 0.95, 0.5) # background pane on 3D axes
431+
#axes3d.yaxis.panecolor: (0.90, 0.90, 0.90, 0.5) # background pane on 3D axes
432+
#axes3d.zaxis.panecolor: (0.925, 0.925, 0.925, 0.5) # background pane on 3D axes
430433

431434
## ***************************************************************************
432435
## * AXIS *

0 commit comments

Comments
 (0)