Skip to content

Commit 36fc63e

Browse files
authored
Merge branch 'matplotlib:main' into logo_guide
2 parents 45c2d05 + 9da2022 commit 36fc63e

33 files changed

+553
-292
lines changed

.github/workflows/codeql-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
persist-credentials: false
3333

3434
- name: Initialize CodeQL
35-
uses: github/codeql-action/init@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
35+
uses: github/codeql-action/init@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
3636
with:
3737
languages: ${{ matrix.language }}
3838

@@ -43,4 +43,4 @@ jobs:
4343
pip install --user -v .
4444
4545
- name: Perform CodeQL Analysis
46-
uses: github/codeql-action/analyze@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
46+
uses: github/codeql-action/analyze@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3

.github/workflows/tests.yml

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ jobs:
6060
extra-requirements: '-r requirements/testing/extra.txt'
6161
# https://github.com/matplotlib/matplotlib/issues/29844
6262
pygobject-ver: '<3.52.0'
63-
- os: ubuntu-22.04-arm
64-
python-version: '3.12'
65-
# https://github.com/matplotlib/matplotlib/issues/29844
66-
pygobject-ver: '<3.52.0'
6763
- name-suffix: "(Extra TeX packages)"
6864
os: ubuntu-22.04
6965
python-version: '3.13'
@@ -77,14 +73,17 @@ jobs:
7773
pygobject-ver: '<3.52.0'
7874
- os: ubuntu-24.04
7975
python-version: '3.12'
80-
- os: macos-13 # This runner is on Intel chips.
81-
# merge numpy and pandas install in nighties test when this runner is dropped
76+
- os: ubuntu-24.04-arm
77+
python-version: '3.12'
78+
- os: macos-14 # This runner is on M1 (arm64) chips.
8279
python-version: '3.11'
80+
# https://github.com/matplotlib/matplotlib/issues/29732
81+
pygobject-ver: '<3.52.0'
8382
- os: macos-14 # This runner is on M1 (arm64) chips.
8483
python-version: '3.12'
8584
# https://github.com/matplotlib/matplotlib/issues/29732
8685
pygobject-ver: '<3.52.0'
87-
- os: macos-14 # This runner is on M1 (arm64) chips.
86+
- os: macos-15 # This runner is on M1 (arm64) chips.
8887
python-version: '3.13'
8988
# https://github.com/matplotlib/matplotlib/issues/29732
9089
pygobject-ver: '<3.52.0'
@@ -149,7 +148,7 @@ jobs:
149148
if [[ "${{ matrix.name-suffix }}" != '(Minimum Versions)' ]]; then
150149
sudo apt-get install -yy --no-install-recommends ffmpeg poppler-utils
151150
fi
152-
if [[ "${{ matrix.os }}" = ubuntu-22.04 || "${{ matrix.os }}" = ubuntu-22.04-arm ]]; then
151+
if [[ "${{ matrix.os }}" = ubuntu-22.04 ]]; then
153152
sudo apt-get install -yy --no-install-recommends \
154153
gir1.2-gtk-4.0 \
155154
libgirepository1.0-dev
@@ -256,7 +255,7 @@ jobs:
256255
)
257256
258257
# PyQt5 does not have any wheels for ARM on Linux.
259-
if [[ "${{ matrix.os }}" != 'ubuntu-22.04-arm' ]]; then
258+
if [[ "${{ matrix.os }}" != 'ubuntu-24.04-arm' ]]; then
260259
python -mpip install --upgrade --only-binary :all: pyqt5 &&
261260
python -c 'import PyQt5.QtCore' &&
262261
echo 'PyQt5 is available' ||
@@ -297,13 +296,7 @@ jobs:
297296
python -m pip install pytz tzdata # Must be installed for Pandas.
298297
python -m pip install \
299298
--index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \
300-
--upgrade --only-binary=:all: numpy
301-
# wheels for intel osx is not always available on nightly wheels index, merge this back into
302-
# the above install command when the OSX-13 (intel) runners are dropped.
303-
python -m pip install \
304-
--index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \
305-
--upgrade --only-binary=:all: pandas || true
306-
299+
--upgrade --only-binary=:all: numpy pandas
307300
308301
- name: Install Matplotlib
309302
run: |
@@ -377,7 +370,7 @@ jobs:
377370
run: |
378371
if [[ "${{ runner.os }}" != 'macOS' ]]; then
379372
LCOV_IGNORE_ERRORS=',' # do not ignore any lcov errors by default
380-
if [[ "${{ matrix.os }}" = ubuntu-24.04 ]]; then
373+
if [[ "${{ matrix.os }}" = ubuntu-24.04 || "${{ matrix.os }}" = ubuntu-24.04-arm ]]; then
381374
# filter mismatch and unused-entity errors detected by lcov 2.x
382375
LCOV_IGNORE_ERRORS='mismatch,unused'
383376
fi

doc/devel/pr_guide.rst

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,10 @@ Workflow
109109
* The PR should :ref:`target the main branch <pr-branch-selection>`.
110110
* Tag with descriptive :ref:`labels <pr-labels>`.
111111
* Set the :ref:`milestone <pr-milestones>`.
112-
* Keep an eye on the :ref:`number of commits <pr-squashing>`.
112+
* :ref:`Review <pr-review>` the contents.
113113
* Approve if all of the above topics are handled.
114-
* :ref:`Merge <pr-merging>` if a sufficient number of approvals is reached.
114+
* Keep an eye on the :ref:`number of commits <pr-squashing>`.
115+
* :ref:`Merge <pr-merging>` if a :ref:`sufficient number of approvals <pr-approval>` is reached.
115116

116117
.. _pr-guidelines-details:
117118

@@ -190,10 +191,27 @@ All Pull Requests should target the main branch. The milestone tag triggers
190191
an :ref:`automatic backport <automated-backports>` for milestones which have
191192
a corresponding branch.
192193

193-
.. _pr-merging:
194+
.. _pr-review:
194195

195-
Merging
196-
-------
196+
Review
197+
------
198+
199+
* Do not let perfect be the enemy of the good, particularly for
200+
documentation or example PRs. If you find yourself making many
201+
small suggestions, either open a PR against the original branch,
202+
push changes to the contributor branch, or merge the PR and then
203+
open a new PR against upstream.
204+
205+
* If you push to a contributor branch leave a comment explaining what
206+
you did, ex "I took the liberty of pushing a small clean-up PR to
207+
your branch, thanks for your work.". If you are going to make
208+
substantial changes to the code or intent of the PR please check
209+
with the contributor first.
210+
211+
.. _pr-approval:
212+
213+
Approval
214+
--------
197215
As a guiding principle, we require two `approvals`_ from core developers (those
198216
with commit rights) before merging a pull request. This two-pairs-of-eyes
199217
strategy shall ensure a consistent project direction and prevent accidental
@@ -229,18 +247,22 @@ Some explicit rules following from this:
229247
A core dev should only champion one PR at a time and we should try to keep
230248
the flow of championed PRs reasonable.
231249

232-
After giving the last required approval, the author of the approval should
233-
merge the PR. PR authors should not self-merge except for when another reviewer
234-
explicitly allows it (e.g., "Approve modulo CI passing, may self merge when
235-
green", or "Take or leave the comments. You may self merge".).
236-
237250
.. _pr-automated-tests:
238251

239252
Automated tests
240253
---------------
241254
Before being merged, a PR should pass the :ref:`automated-tests`. If you are
242255
unsure why a test is failing, ask on the PR or in our :ref:`communication-channels`
243256

257+
.. _pr-merging:
258+
259+
Merging
260+
-------
261+
After giving the last required :ref:`approval <pr-approval>`, the author of the
262+
approval should merge the PR. PR authors should not self-merge except for when
263+
another reviewer explicitly allows it (e.g., "Approve modulo CI passing, may
264+
self-merge when green", or "Take or leave the comments. You may self merge".).
265+
244266
.. _pr-squashing:
245267

246268
Number of commits and squashing
@@ -252,19 +274,6 @@ Number of commits and squashing
252274
about it is to eliminate binary files (ex multiple test image
253275
re-generations) and to remove upstream merges.
254276

255-
* Do not let perfect be the enemy of the good, particularly for
256-
documentation or example PRs. If you find yourself making many
257-
small suggestions, either open a PR against the original branch,
258-
push changes to the contributor branch, or merge the PR and then
259-
open a new PR against upstream.
260-
261-
* If you push to a contributor branch leave a comment explaining what
262-
you did, ex "I took the liberty of pushing a small clean-up PR to
263-
your branch, thanks for your work.". If you are going to make
264-
substantial changes to the code or intent of the PR please check
265-
with the contributor first.
266-
267-
268277
.. _branches_and_backports:
269278

270279
Branches and backports
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
Figures can be attached to and removed from pyplot
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Figures can now be attached to and removed from management through pyplot, which in
4+
the background also means a less strict coupling to backends.
5+
6+
In particular, standalone figures (created with the `.Figure` constructor) can now be
7+
registered with the `.pyplot` module by calling ``plt.figure(fig)``. This allows to
8+
show them with ``plt.show()`` as you would do with any figure created with pyplot
9+
factory methods such as ``plt.figure()`` or ``plt.subplots()``.
10+
11+
When closing a shown figure window, the related figure is reset to the standalone
12+
state, i.e. it's not visible to pyplot anymore, but if you still hold a reference
13+
to it, you can continue to work with it (e.g. do ``fig.savefig()``, or re-add it
14+
to pyplot with ``plt.figure(fig)`` and then show it again).
15+
16+
The following is now possible - though the example is exaggerated to show what's
17+
possible. In practice, you'll stick with much simpler versions for better
18+
consistency ::
19+
20+
import matplotlib.pyplot as plt
21+
from matplotlib.figure import Figure
22+
23+
# Create a standalone figure
24+
fig = Figure()
25+
ax = fig.add_subplot()
26+
ax.plot([1, 2, 3], [4, 5, 6])
27+
28+
# Register it with pyplot
29+
plt.figure(fig)
30+
31+
# Modify the figure through pyplot
32+
plt.xlabel("x label")
33+
34+
# Show the figure
35+
plt.show()
36+
37+
# Close the figure window through the GUI
38+
39+
# Continue to work on the figure
40+
fig.savefig("my_figure.png")
41+
ax.set_ylabel("y label")
42+
43+
# Re-register the figure and show it again
44+
plt.figure(fig)
45+
plt.show()
46+
47+
Technical detail: Standalone figures use `.FigureCanvasBase` as canvas. This is
48+
replaced by a backend-dependent subclass when registering with pyplot, and is
49+
reset to `.FigureCanvasBase` when the figure is closed. `.Figure.savefig` uses
50+
the current canvas to save the figure (if possible). Since `.FigureCanvasBase`
51+
can not render the figure, when saving the figure, it will fallback to a suitable
52+
canvas subclass, e.g. `.FigureCanvasAgg` for raster outputs such as png.
53+
Any Agg-based backend will create the same file output. However, there may be
54+
slight differences for non-Agg backends; e.g. if you use "GTK4Cairo" as
55+
interactive backend, ``fig.savefig("file.png")`` may create a slightly different
56+
image depending on whether the figure is registered with pyplot or not. In
57+
general, you should not store a reference to the canvas, but rather always
58+
obtain it from the figure with ``fig.canvas``. This will return the current
59+
canvas, which is either the original `.FigureCanvasBase` or a backend-dependent
60+
subclass, depending on whether the figure is registered with pyplot or not.
61+
Additionally, the swapping of the canvas currently does not play well with
62+
blitting of matplotlib widgets; in such cases either deactivate blitting or do not
63+
continue to use the figure (e.g. saving it after closing the window).
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Zooming using mouse wheel
2+
~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
``Ctrl+MouseWheel`` can be used to zoom in the plot windows.
5+
6+
The zoom focusses on the mouse pointer, and keeps the aspect ratio of the axes.
7+
8+
Zooming is currently only supported on rectilinear Axes.

galleries/users_explain/text/fonts.py

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,24 @@
2727
Matplotlib supports three font specifications (in addition to pdf 'core fonts',
2828
which are explained later in the guide):
2929
30-
.. table:: Type of Fonts
31-
32-
+--------------------------+----------------------------+----------------------------+
33-
| Type 1 (PDF with usetex) | Type 3 (PDF/PS) | TrueType (PDF) |
34-
+==========================+============================+============================+
35-
| One of the oldest types, | Similar to Type 1 in | Newer than previous types, |
36-
| introduced by Adobe | terms of introduction | used commonly today, |
37-
| | | introduced by Apple |
38-
+--------------------------+----------------------------+----------------------------+
39-
| Restricted subset of | Full PostScript language, | Includes a virtual machine |
40-
| PostScript, charstrings | allows embedding arbitrary | that can execute code! |
41-
| are in bytecode | code (in theory, even | |
42-
| | render fractals when | |
43-
| | rasterizing!) | |
44-
+--------------------------+----------------------------+----------------------------+
45-
| Supports font | Does not support font | Supports font hinting |
46-
| hinting | hinting | (virtual machine processes |
47-
| | | the "hints") |
48-
+--------------------------+----------------------------+----------------------------+
49-
| Subsetted by code in | Subsetted via external module |
50-
| `matplotlib._type1font` | `fontTools <https://github.com/fonttools/fonttools>`__ |
51-
+--------------------------+----------------------------+----------------------------+
30+
.. table:: Types of Fonts
31+
32+
+--------------------------+----------------------------+-------------------------------+
33+
| Type 1 (PDF with usetex) | Type 3 (PDF/PS) | TrueType (PDF) / Type 42 (PS) |
34+
+==========================+============================+===============================+
35+
| Old font types introduced by Adobe. | Newer font type introduced by |
36+
| | Apple; commonly used today. |
37+
+--------------------------+----------------------------+-------------------------------+
38+
| Restricted subset of | Full PostScript language, | Includes a virtual machine |
39+
| PostScript, charstrings | allows embedding arbitrary | that can execute code. |
40+
| are in bytecode. | code. | |
41+
+--------------------------+----------------------------+-------------------------------+
42+
| Supports font hinting. | Does not support font | Supports font hinting, |
43+
| | hinting. | through the virtual machine. |
44+
+--------------------------+----------------------------+-------------------------------+
45+
| Subsetted by code in | Subsetted via external module |
46+
| `matplotlib._type1font`. | `fontTools <https://github.com/fonttools/fonttools>`__. |
47+
+--------------------------+----------------------------+-------------------------------+
5248
5349
.. note::
5450
@@ -59,23 +55,9 @@
5955
6056
__ https://helpx.adobe.com/fonts/kb/postscript-type-1-fonts-end-of-support.html
6157
62-
Other font specifications which Matplotlib supports:
63-
64-
- Type 42 fonts (PS):
65-
66-
- PostScript wrapper around TrueType fonts
67-
- 42 is the `Answer to Life, the Universe, and Everything!
68-
<https://en.wikipedia.org/wiki/Answer_to_Life,_the_Universe,_and_Everything>`_
69-
- Matplotlib uses the external library
70-
`fontTools <https://github.com/fonttools/fonttools>`__ to subset these types of
71-
fonts
72-
73-
- OpenType fonts:
74-
75-
- OpenType is a new standard for digital type fonts, developed jointly by
76-
Adobe and Microsoft
77-
- Generally contain a much larger character set!
78-
- Limited support with Matplotlib
58+
Matplotlib also provides limited support for OpenType fonts, a newer standard
59+
developed jointly by Adobe and Microsoft; such fonts generally contain a much
60+
larger character set.
7961
8062
Font subsetting
8163
^^^^^^^^^^^^^^^
@@ -201,4 +183,4 @@
201183
202184
A majority of this work was done by Aitik Gupta supported by Google Summer of
203185
Code 2021.
204-
"""
186+
""" # noqa: E501

lib/matplotlib/_pylab_helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ def destroy(cls, num):
5353
two managers share the same number.
5454
"""
5555
if all(hasattr(num, attr) for attr in ["num", "destroy"]):
56+
# num is a manager-like instance (not necessarily a
57+
# FigureManagerBase subclass)
5658
manager = num
5759
if cls.figs.get(manager.num) is manager:
5860
cls.figs.pop(manager.num)

0 commit comments

Comments
 (0)