From 4b30b1d938b1ccad1e96b35ec11292e9fb8f05fd Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 12 Aug 2024 19:52:20 -0400 Subject: [PATCH 01/49] BLD: bump branch away from tag So the tarballs from GitHub are stable. From 3aea791026cabe9b9bdaba6d9a23c122bbf04115 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 12 Aug 2024 20:13:22 -0400 Subject: [PATCH 02/49] DOC: Add Zenodo DOI for 3.9.2 --- doc/_static/zenodo_cache/13308876.svg | 35 +++++++++++++++++++++++++++ doc/project/citing.rst | 3 +++ tools/cache_zenodo_svg.py | 1 + 3 files changed, 39 insertions(+) create mode 100644 doc/_static/zenodo_cache/13308876.svg diff --git a/doc/_static/zenodo_cache/13308876.svg b/doc/_static/zenodo_cache/13308876.svg new file mode 100644 index 000000000000..749bc3c19026 --- /dev/null +++ b/doc/_static/zenodo_cache/13308876.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + DOI + + + DOI + + + 10.5281/zenodo.13308876 + + + 10.5281/zenodo.13308876 + + + \ No newline at end of file diff --git a/doc/project/citing.rst b/doc/project/citing.rst index e0b99995ad11..38c989fca195 100644 --- a/doc/project/citing.rst +++ b/doc/project/citing.rst @@ -32,6 +32,9 @@ By version .. START OF AUTOGENERATED +v3.9.2 + .. image:: ../_static/zenodo_cache/13308876.svg + :target: https://doi.org/10.5281/zenodo.13308876 v3.9.1 .. image:: ../_static/zenodo_cache/12652732.svg :target: https://doi.org/10.5281/zenodo.12652732 diff --git a/tools/cache_zenodo_svg.py b/tools/cache_zenodo_svg.py index 1dc2fbba020b..40814d21573c 100644 --- a/tools/cache_zenodo_svg.py +++ b/tools/cache_zenodo_svg.py @@ -63,6 +63,7 @@ def _get_xdg_cache_dir(): if __name__ == "__main__": data = { + "v3.9.2": "13308876", "v3.9.1": "12652732", "v3.9.0": "11201097", "v3.8.4": "10916799", From d04b2f64fe2fdc3f83707229d64d1516bb56405d Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 12 Aug 2024 21:55:17 -0400 Subject: [PATCH 03/49] DOC: Fix a typo in GitHub stats --- doc/users/github_stats.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/github_stats.rst b/doc/users/github_stats.rst index 00c3e5d656a1..d357a6759d30 100644 --- a/doc/users/github_stats.rst +++ b/doc/users/github_stats.rst @@ -89,7 +89,7 @@ Issues (9): * :ghissue:`28250`: [Doc]: Sphinx gallery links mispointed for Axes3D methods * :ghissue:`28574`: [Bug]: Nondeterministic behavior with subplot spacing and constrained layout * :ghissue:`28626`: [Doc]: Remove old TODO's from animation.py -* :ghissue:`28648`: [Bug]: format_image_data on an image of only zeros produses a large number of zeros +* :ghissue:`28648`: [Bug]: format_image_data on an image of only zeros produces a large number of zeros * :ghissue:`28624`: [Bug]: Bad type hint in ``_AxesBase.twinx()`` * :ghissue:`28567`: [Bug]: sticky edge related changes for datetime plots * :ghissue:`28533`: [Doc]: Stackplot hatch functionality has version dependencies From 8e2d7914a2c8943187405661be3e876537c32e54 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 14 Aug 2024 16:44:38 -0400 Subject: [PATCH 04/49] TST: Guard against PyGObject existing, but not gobject-introspection --- lib/matplotlib/tests/test_backends_interactive.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py index d624b5db0ac2..2c6b61a48438 100644 --- a/lib/matplotlib/tests/test_backends_interactive.py +++ b/lib/matplotlib/tests/test_backends_interactive.py @@ -81,10 +81,18 @@ def _get_available_interactive_backends(): elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'): reason = "macosx backend fails on Azure" elif env["MPLBACKEND"].startswith('gtk'): - import gi # type: ignore + try: + import gi # type: ignore + except ImportError: + # Though we check that `gi` exists above, it is possible that its + # C-level dependencies are not available, and then it still raises an + # `ImportError`, so guard against that. + available_gtk_versions = [] + else: + gi_repo = gi.Repository.get_default() + available_gtk_versions = gi_repo.enumerate_versions('Gtk') version = env["MPLBACKEND"][3] - repo = gi.Repository.get_default() - if f'{version}.0' not in repo.enumerate_versions('Gtk'): + if f'{version}.0' not in available_gtk_versions: reason = "no usable GTK bindings" marks = [] if reason: From f6b32660a348aa027b25709cc3d8218b017e8db5 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 14 Aug 2024 17:02:23 -0400 Subject: [PATCH 05/49] BLD: Avoid pybind11 2.13.3 due to Windows quoting bug See https://github.com/pybind/pybind11/issues/5300#issuecomment-2287698500 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 52bbe308c0f9..891ef87e4342 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ requires-python = ">=3.9" dev = [ "meson-python>=0.13.1", "numpy>=1.25", - "pybind11>=2.6", + "pybind11>=2.6,!=2.13.3", "setuptools_scm>=7", # Not required by us but setuptools_scm without a version, cso _if_ # installed, then setuptools_scm 8 requires at least this version. @@ -73,7 +73,7 @@ build-backend = "mesonpy" # Also keep in sync with optional dependencies above. requires = [ "meson-python>=0.13.1", - "pybind11>=2.6", + "pybind11>=2.6,!=2.13.3", "setuptools_scm>=7", # Comments on numpy build requirement range: From cb124887a10c2e69e70974847a47f320353e791c Mon Sep 17 00:00:00 2001 From: hannah Date: Thu, 15 Aug 2024 18:21:14 -0400 Subject: [PATCH 06/49] Backport PR #28732: Renames the minumumSizeHint method to minimumSizeHint --- lib/matplotlib/backends/backend_qt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_qt.py b/lib/matplotlib/backends/backend_qt.py index 6603883075d4..242c6fdbf9f9 100644 --- a/lib/matplotlib/backends/backend_qt.py +++ b/lib/matplotlib/backends/backend_qt.py @@ -393,7 +393,7 @@ def sizeHint(self): w, h = self.get_width_height() return QtCore.QSize(w, h) - def minumumSizeHint(self): + def minimumSizeHint(self): return QtCore.QSize(10, 10) @staticmethod From 3900fa24aa082c1727ca274b98747933f1578671 Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Wed, 21 Aug 2024 08:22:23 +0100 Subject: [PATCH 07/49] Backport PR #28737: TST: Fix image comparison directory for test_striped_lines --- lib/matplotlib/tests/test_collections.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 23e951b17a2f..c4f98d4eeb45 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -1316,7 +1316,6 @@ def test_check_offsets_dtype(): @pytest.mark.parametrize('gapcolor', ['orange', ['r', 'k']]) @check_figures_equal(extensions=['png']) -@mpl.rc_context({'lines.linewidth': 20}) def test_striped_lines(fig_test, fig_ref, gapcolor): ax_test = fig_test.add_subplot(111) ax_ref = fig_ref.add_subplot(111) @@ -1328,11 +1327,12 @@ def test_striped_lines(fig_test, fig_ref, gapcolor): x = range(1, 6) linestyles = [':', '-', '--'] - ax_test.vlines(x, 0, 1, linestyle=linestyles, gapcolor=gapcolor, alpha=0.5) + ax_test.vlines(x, 0, 1, linewidth=20, linestyle=linestyles, gapcolor=gapcolor, + alpha=0.5) if isinstance(gapcolor, str): gapcolor = [gapcolor] for x, gcol, ls in zip(x, itertools.cycle(gapcolor), itertools.cycle(linestyles)): - ax_ref.axvline(x, 0, 1, linestyle=ls, gapcolor=gcol, alpha=0.5) + ax_ref.axvline(x, 0, 1, linewidth=20, linestyle=ls, gapcolor=gcol, alpha=0.5) From fc5bc4a50b6c16cde5e21e122fb370862b56148c Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:17:02 +0100 Subject: [PATCH 08/49] Backport PR #28739: Tweak interactivity docs wording (and fix capitalization). --- galleries/users_explain/figure/event_handling.rst | 15 +++++++++------ galleries/users_explain/figure/interactive.rst | 2 +- .../users_explain/figure/interactive_guide.rst | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/galleries/users_explain/figure/event_handling.rst b/galleries/users_explain/figure/event_handling.rst index 49d73afeb366..32da038634ae 100644 --- a/galleries/users_explain/figure/event_handling.rst +++ b/galleries/users_explain/figure/event_handling.rst @@ -251,7 +251,8 @@ is created every time a mouse is pressed:: def __call__(self, event): print('click', event) - if event.inaxes!=self.line.axes: return + if event.inaxes != self.line.axes: + return self.xs.append(event.xdata) self.ys.append(event.ydata) self.line.set_data(self.xs, self.ys) @@ -277,17 +278,19 @@ event.ydata)``. In addition to the ``LocationEvent`` attributes, it also has: Draggable rectangle exercise ---------------------------- -Write draggable rectangle class that is initialized with a +Write a draggable rectangle class that is initialized with a `.Rectangle` instance but will move its ``xy`` -location when dragged. Hint: you will need to store the original -``xy`` location of the rectangle which is stored as rect.xy and +location when dragged. + +Hint: You will need to store the original +``xy`` location of the rectangle which is stored as ``rect.xy`` and connect to the press, motion and release mouse events. When the mouse is pressed, check to see if the click occurs over your rectangle (see `.Rectangle.contains`) and if it does, store -the rectangle xy and the location of the mouse click in data coords. +the rectangle xy and the location of the mouse click in data coordinates. In the motion event callback, compute the deltax and deltay of the mouse movement, and add those deltas to the origin of the rectangle -you stored. The redraw the figure. On the button release event, just +you stored, then redraw the figure. On the button release event, just reset all the button press data you stored as None. Here is the solution:: diff --git a/galleries/users_explain/figure/interactive.rst b/galleries/users_explain/figure/interactive.rst index 6fd908fcac7a..b06283152e50 100644 --- a/galleries/users_explain/figure/interactive.rst +++ b/galleries/users_explain/figure/interactive.rst @@ -10,7 +10,7 @@ Interactive figures =================== -When working with data, interactivity can be invaluable. The pan/zoom and +Interactivity can be invaluable when exploring plots. The pan/zoom and mouse-location tools built into the Matplotlib GUI windows are often sufficient, but you can also use the event system to build customized data exploration tools. diff --git a/galleries/users_explain/figure/interactive_guide.rst b/galleries/users_explain/figure/interactive_guide.rst index 3b6f527f6d42..b08231e84f7e 100644 --- a/galleries/users_explain/figure/interactive_guide.rst +++ b/galleries/users_explain/figure/interactive_guide.rst @@ -236,7 +236,7 @@ which would poll for new data and update the figure at 1Hz. .. _spin_event_loop: -Explicitly spinning the event Loop +Explicitly spinning the event loop ---------------------------------- .. autosummary:: From cbc42296dce9d199ef6f33ee6a893ebb11fbfac5 Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:17:02 +0100 Subject: [PATCH 09/49] Backport PR #28739: Tweak interactivity docs wording (and fix capitalization). --- galleries/users_explain/figure/event_handling.rst | 15 +++++++++------ galleries/users_explain/figure/interactive.rst | 2 +- .../users_explain/figure/interactive_guide.rst | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/galleries/users_explain/figure/event_handling.rst b/galleries/users_explain/figure/event_handling.rst index 49d73afeb366..32da038634ae 100644 --- a/galleries/users_explain/figure/event_handling.rst +++ b/galleries/users_explain/figure/event_handling.rst @@ -251,7 +251,8 @@ is created every time a mouse is pressed:: def __call__(self, event): print('click', event) - if event.inaxes!=self.line.axes: return + if event.inaxes != self.line.axes: + return self.xs.append(event.xdata) self.ys.append(event.ydata) self.line.set_data(self.xs, self.ys) @@ -277,17 +278,19 @@ event.ydata)``. In addition to the ``LocationEvent`` attributes, it also has: Draggable rectangle exercise ---------------------------- -Write draggable rectangle class that is initialized with a +Write a draggable rectangle class that is initialized with a `.Rectangle` instance but will move its ``xy`` -location when dragged. Hint: you will need to store the original -``xy`` location of the rectangle which is stored as rect.xy and +location when dragged. + +Hint: You will need to store the original +``xy`` location of the rectangle which is stored as ``rect.xy`` and connect to the press, motion and release mouse events. When the mouse is pressed, check to see if the click occurs over your rectangle (see `.Rectangle.contains`) and if it does, store -the rectangle xy and the location of the mouse click in data coords. +the rectangle xy and the location of the mouse click in data coordinates. In the motion event callback, compute the deltax and deltay of the mouse movement, and add those deltas to the origin of the rectangle -you stored. The redraw the figure. On the button release event, just +you stored, then redraw the figure. On the button release event, just reset all the button press data you stored as None. Here is the solution:: diff --git a/galleries/users_explain/figure/interactive.rst b/galleries/users_explain/figure/interactive.rst index 6fd908fcac7a..b06283152e50 100644 --- a/galleries/users_explain/figure/interactive.rst +++ b/galleries/users_explain/figure/interactive.rst @@ -10,7 +10,7 @@ Interactive figures =================== -When working with data, interactivity can be invaluable. The pan/zoom and +Interactivity can be invaluable when exploring plots. The pan/zoom and mouse-location tools built into the Matplotlib GUI windows are often sufficient, but you can also use the event system to build customized data exploration tools. diff --git a/galleries/users_explain/figure/interactive_guide.rst b/galleries/users_explain/figure/interactive_guide.rst index 3b6f527f6d42..b08231e84f7e 100644 --- a/galleries/users_explain/figure/interactive_guide.rst +++ b/galleries/users_explain/figure/interactive_guide.rst @@ -236,7 +236,7 @@ which would poll for new data and update the figure at 1Hz. .. _spin_event_loop: -Explicitly spinning the event Loop +Explicitly spinning the event loop ---------------------------------- .. autosummary:: From d9d1a4d3f6612e9349f1607f46f359bdce8934f6 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:20:39 +0200 Subject: [PATCH 10/49] Backport PR #28743: Minor fixes in ticker docs --- lib/matplotlib/ticker.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 2b00937f9e29..d824bbe3b6e2 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -435,10 +435,10 @@ class ScalarFormatter(Formatter): lim = (1_000_000, 1_000_010) fig, (ax1, ax2, ax3) = plt.subplots(3, 1, gridspec_kw={'hspace': 2}) - ax1.set(title='offset_notation', xlim=lim) + ax1.set(title='offset notation', xlim=lim) ax2.set(title='scientific notation', xlim=lim) ax2.xaxis.get_major_formatter().set_useOffset(False) - ax3.set(title='floating point notation', xlim=lim) + ax3.set(title='floating-point notation', xlim=lim) ax3.xaxis.get_major_formatter().set_useOffset(False) ax3.xaxis.get_major_formatter().set_scientific(False) @@ -1146,10 +1146,10 @@ def __init__( Parameters ---------- use_overline : bool, default: False - If x > 1/2, with x = 1-v, indicate if x should be displayed as - $\overline{v}$. The default is to display $1-v$. + If x > 1/2, with x = 1 - v, indicate if x should be displayed as + $\overline{v}$. The default is to display $1 - v$. - one_half : str, default: r"\frac{1}{2}" + one_half : str, default: r"\\frac{1}{2}" The string used to represent 1/2. minor : bool, default: False @@ -1179,9 +1179,9 @@ def use_overline(self, use_overline): Parameters ---------- - use_overline : bool, default: False - If x > 1/2, with x = 1-v, indicate if x should be displayed as - $\overline{v}$. The default is to display $1-v$. + use_overline : bool + If x > 1/2, with x = 1 - v, indicate if x should be displayed as + $\overline{v}$. The default is to display $1 - v$. """ self._use_overline = use_overline @@ -1189,7 +1189,7 @@ def set_one_half(self, one_half): r""" Set the way one half is displayed. - one_half : str, default: r"\frac{1}{2}" + one_half : str The string used to represent 1/2. """ self._one_half = one_half @@ -1707,14 +1707,14 @@ def tick_values(self, vmin, vmax): class FixedLocator(Locator): - """ + r""" Place ticks at a set of fixed values. If *nbins* is None ticks are placed at all values. Otherwise, the *locs* array of - possible positions will be subsampled to keep the number of ticks <= - :math:`nbins* +1`. The subsampling will be done to include the smallest absolute - value; for example, if zero is included in the array of possibilities, then it of - the chosen ticks. + possible positions will be subsampled to keep the number of ticks + :math:`\leq nbins + 1`. The subsampling will be done to include the smallest + absolute value; for example, if zero is included in the array of possibilities, then + it will be included in the chosen ticks. """ def __init__(self, locs, nbins=None): @@ -1861,9 +1861,9 @@ def __init__(self, base=1.0, offset=0.0): """ Parameters ---------- - base : float > 0 + base : float > 0, default: 1.0 Interval between ticks. - offset : float + offset : float, default: 0.0 Value added to each multiple of *base*. .. versionadded:: 3.8 @@ -1877,9 +1877,9 @@ def set_params(self, base=None, offset=None): Parameters ---------- - base : float > 0 + base : float > 0, optional Interval between ticks. - offset : float + offset : float, optional Value added to each multiple of *base*. .. versionadded:: 3.8 From 83251ac2a1d780dc4af2bacab07b43552c5b7a70 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 22 Aug 2024 14:50:03 -0400 Subject: [PATCH 11/49] Backport PR #28271: Fix draggable legend disappearing when picking while use_blit=True --- lib/matplotlib/offsetbox.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/offsetbox.py b/lib/matplotlib/offsetbox.py index 32c5bafcde1d..194b950a8a30 100644 --- a/lib/matplotlib/offsetbox.py +++ b/lib/matplotlib/offsetbox.py @@ -1486,11 +1486,13 @@ def on_motion(self, evt): self.canvas.draw() def on_pick(self, evt): - if self._check_still_parented() and evt.artist == self.ref_artist: - self.mouse_x = evt.mouseevent.x - self.mouse_y = evt.mouseevent.y - self.got_artist = True - if self._use_blit: + if self._check_still_parented(): + if evt.artist == self.ref_artist: + self.mouse_x = evt.mouseevent.x + self.mouse_y = evt.mouseevent.y + self.save_offset() + self.got_artist = True + if self.got_artist and self._use_blit: self.ref_artist.set_animated(True) self.canvas.draw() self.background = \ @@ -1498,13 +1500,15 @@ def on_pick(self, evt): self.ref_artist.draw( self.ref_artist.figure._get_renderer()) self.canvas.blit() - self.save_offset() def on_release(self, event): if self._check_still_parented() and self.got_artist: self.finalize_offset() self.got_artist = False if self._use_blit: + self.canvas.restore_region(self.background) + self.ref_artist.draw(self.ref_artist.figure._get_renderer()) + self.canvas.blit() self.ref_artist.set_animated(False) def _check_still_parented(self): From 4439116246b1f74e6dda7a11d96602c3912c01b9 Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Sat, 7 Sep 2024 14:33:56 +0100 Subject: [PATCH 12/49] Backport PR #28706: Add Returns info to to_jshtml docstring --- lib/matplotlib/animation.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index 5a4764f1a79f..b402c5fdb4da 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -1311,6 +1311,12 @@ def to_jshtml(self, fps=None, embed_frames=True, default_mode=None): What to do when the animation ends. Must be one of ``{'loop', 'once', 'reflect'}``. Defaults to ``'loop'`` if the *repeat* parameter is True, otherwise ``'once'``. + + Returns + ------- + str + An HTML representation of the animation embedded as a js object as + produced with the `.HTMLWriter`. """ if fps is None and hasattr(self, '_interval'): # Convert interval in ms to frames per second From 7c370eac988c51dea9d6fca285636ebfcdeba55c Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:44:57 +0100 Subject: [PATCH 13/49] Backport PR #28790: DOC: Fix duplicate Figure.set_dpi entry --- doc/api/figure_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/figure_api.rst b/doc/api/figure_api.rst index 2371e5a9a863..5dd3adbfec9f 100644 --- a/doc/api/figure_api.rst +++ b/doc/api/figure_api.rst @@ -91,7 +91,7 @@ Figure geometry Figure.get_figwidth Figure.dpi Figure.set_dpi - Figure.set_dpi + Figure.get_dpi Subplot layout -------------- From cf7e7ae718ced0a8b2bbf7aa2d30b141fa5eeb8c Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:44:57 +0100 Subject: [PATCH 14/49] Backport PR #28790: DOC: Fix duplicate Figure.set_dpi entry --- doc/api/figure_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/figure_api.rst b/doc/api/figure_api.rst index 2371e5a9a863..5dd3adbfec9f 100644 --- a/doc/api/figure_api.rst +++ b/doc/api/figure_api.rst @@ -91,7 +91,7 @@ Figure geometry Figure.get_figwidth Figure.dpi Figure.set_dpi - Figure.set_dpi + Figure.get_dpi Subplot layout -------------- From 88309f528843195ec1e25d75ea5cf148a40bcd8d Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 11 Sep 2024 16:54:17 -0400 Subject: [PATCH 15/49] Backport PR #28798: DOC: Correctly list modules that have been internalized --- doc/api/_afm_api.rst | 8 ++++++++ doc/api/_docstring_api.rst | 8 ++++++++ doc/api/_tight_bbox_api.rst | 8 ++++++++ doc/api/_tight_layout_api.rst | 8 ++++++++ doc/api/_type1font.rst | 8 ++++++++ doc/api/afm_api.rst | 13 ------------- doc/api/docstring_api.rst | 13 ------------- doc/api/index.rst | 10 +++++----- doc/api/tight_bbox_api.rst | 13 ------------- doc/api/tight_layout_api.rst | 13 ------------- doc/api/type1font.rst | 13 ------------- 11 files changed, 45 insertions(+), 70 deletions(-) create mode 100644 doc/api/_afm_api.rst create mode 100644 doc/api/_docstring_api.rst create mode 100644 doc/api/_tight_bbox_api.rst create mode 100644 doc/api/_tight_layout_api.rst create mode 100644 doc/api/_type1font.rst delete mode 100644 doc/api/afm_api.rst delete mode 100644 doc/api/docstring_api.rst delete mode 100644 doc/api/tight_bbox_api.rst delete mode 100644 doc/api/tight_layout_api.rst delete mode 100644 doc/api/type1font.rst diff --git a/doc/api/_afm_api.rst b/doc/api/_afm_api.rst new file mode 100644 index 000000000000..4e2ac4997272 --- /dev/null +++ b/doc/api/_afm_api.rst @@ -0,0 +1,8 @@ +******************* +``matplotlib._afm`` +******************* + +.. automodule:: matplotlib._afm + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_docstring_api.rst b/doc/api/_docstring_api.rst new file mode 100644 index 000000000000..040a3653a87b --- /dev/null +++ b/doc/api/_docstring_api.rst @@ -0,0 +1,8 @@ +************************* +``matplotlib._docstring`` +************************* + +.. automodule:: matplotlib._docstring + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_tight_bbox_api.rst b/doc/api/_tight_bbox_api.rst new file mode 100644 index 000000000000..826e051fcf6d --- /dev/null +++ b/doc/api/_tight_bbox_api.rst @@ -0,0 +1,8 @@ +************************** +``matplotlib._tight_bbox`` +************************** + +.. automodule:: matplotlib._tight_bbox + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_tight_layout_api.rst b/doc/api/_tight_layout_api.rst new file mode 100644 index 000000000000..ac4f66f280e1 --- /dev/null +++ b/doc/api/_tight_layout_api.rst @@ -0,0 +1,8 @@ +**************************** +``matplotlib._tight_layout`` +**************************** + +.. automodule:: matplotlib._tight_layout + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_type1font.rst b/doc/api/_type1font.rst new file mode 100644 index 000000000000..1a9ff2292887 --- /dev/null +++ b/doc/api/_type1font.rst @@ -0,0 +1,8 @@ +************************* +``matplotlib._type1font`` +************************* + +.. automodule:: matplotlib._type1font + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/afm_api.rst b/doc/api/afm_api.rst deleted file mode 100644 index bcae04150909..000000000000 --- a/doc/api/afm_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -****************** -``matplotlib.afm`` -****************** - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._afm - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/docstring_api.rst b/doc/api/docstring_api.rst deleted file mode 100644 index 38a73a2e83d1..000000000000 --- a/doc/api/docstring_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -************************ -``matplotlib.docstring`` -************************ - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._docstring - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/index.rst b/doc/api/index.rst index 70c3b5343e7a..53f397a6817a 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -79,7 +79,6 @@ Alphabetical list of modules: :maxdepth: 1 matplotlib_configuration_api.rst - afm_api.rst animation_api.rst artist_api.rst axes_api.rst @@ -98,7 +97,6 @@ Alphabetical list of modules: container_api.rst contour_api.rst dates_api.rst - docstring_api.rst dviread.rst figure_api.rst font_manager_api.rst @@ -134,16 +132,18 @@ Alphabetical list of modules: text_api.rst texmanager_api.rst ticker_api.rst - tight_bbox_api.rst - tight_layout_api.rst transformations.rst tri_api.rst - type1font.rst typing_api.rst units_api.rst widgets_api.rst + _afm_api.rst _api_api.rst + _docstring_api.rst _enums_api.rst + _type1font.rst + _tight_bbox_api.rst + _tight_layout_api.rst toolkits/mplot3d.rst toolkits/axes_grid1.rst toolkits/axisartist.rst diff --git a/doc/api/tight_bbox_api.rst b/doc/api/tight_bbox_api.rst deleted file mode 100644 index 9e8dd2fa66f9..000000000000 --- a/doc/api/tight_bbox_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -************************* -``matplotlib.tight_bbox`` -************************* - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._tight_bbox - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/tight_layout_api.rst b/doc/api/tight_layout_api.rst deleted file mode 100644 index 35f92e3ddced..000000000000 --- a/doc/api/tight_layout_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -*************************** -``matplotlib.tight_layout`` -*************************** - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._tight_layout - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/type1font.rst b/doc/api/type1font.rst deleted file mode 100644 index 00ef38f4d447..000000000000 --- a/doc/api/type1font.rst +++ /dev/null @@ -1,13 +0,0 @@ -************************ -``matplotlib.type1font`` -************************ - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._type1font - :members: - :undoc-members: - :show-inheritance: From 259b3ee84784341b50696206d559f67c74ba9c89 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 11 Sep 2024 16:54:17 -0400 Subject: [PATCH 16/49] Backport PR #28798: DOC: Correctly list modules that have been internalized --- doc/api/_afm_api.rst | 8 ++++++++ doc/api/_docstring_api.rst | 8 ++++++++ doc/api/_tight_bbox_api.rst | 8 ++++++++ doc/api/_tight_layout_api.rst | 8 ++++++++ doc/api/_type1font.rst | 8 ++++++++ doc/api/afm_api.rst | 13 ------------- doc/api/docstring_api.rst | 13 ------------- doc/api/index.rst | 10 +++++----- doc/api/tight_bbox_api.rst | 13 ------------- doc/api/tight_layout_api.rst | 13 ------------- doc/api/type1font.rst | 13 ------------- 11 files changed, 45 insertions(+), 70 deletions(-) create mode 100644 doc/api/_afm_api.rst create mode 100644 doc/api/_docstring_api.rst create mode 100644 doc/api/_tight_bbox_api.rst create mode 100644 doc/api/_tight_layout_api.rst create mode 100644 doc/api/_type1font.rst delete mode 100644 doc/api/afm_api.rst delete mode 100644 doc/api/docstring_api.rst delete mode 100644 doc/api/tight_bbox_api.rst delete mode 100644 doc/api/tight_layout_api.rst delete mode 100644 doc/api/type1font.rst diff --git a/doc/api/_afm_api.rst b/doc/api/_afm_api.rst new file mode 100644 index 000000000000..4e2ac4997272 --- /dev/null +++ b/doc/api/_afm_api.rst @@ -0,0 +1,8 @@ +******************* +``matplotlib._afm`` +******************* + +.. automodule:: matplotlib._afm + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_docstring_api.rst b/doc/api/_docstring_api.rst new file mode 100644 index 000000000000..040a3653a87b --- /dev/null +++ b/doc/api/_docstring_api.rst @@ -0,0 +1,8 @@ +************************* +``matplotlib._docstring`` +************************* + +.. automodule:: matplotlib._docstring + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_tight_bbox_api.rst b/doc/api/_tight_bbox_api.rst new file mode 100644 index 000000000000..826e051fcf6d --- /dev/null +++ b/doc/api/_tight_bbox_api.rst @@ -0,0 +1,8 @@ +************************** +``matplotlib._tight_bbox`` +************************** + +.. automodule:: matplotlib._tight_bbox + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_tight_layout_api.rst b/doc/api/_tight_layout_api.rst new file mode 100644 index 000000000000..ac4f66f280e1 --- /dev/null +++ b/doc/api/_tight_layout_api.rst @@ -0,0 +1,8 @@ +**************************** +``matplotlib._tight_layout`` +**************************** + +.. automodule:: matplotlib._tight_layout + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/_type1font.rst b/doc/api/_type1font.rst new file mode 100644 index 000000000000..1a9ff2292887 --- /dev/null +++ b/doc/api/_type1font.rst @@ -0,0 +1,8 @@ +************************* +``matplotlib._type1font`` +************************* + +.. automodule:: matplotlib._type1font + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/afm_api.rst b/doc/api/afm_api.rst deleted file mode 100644 index bcae04150909..000000000000 --- a/doc/api/afm_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -****************** -``matplotlib.afm`` -****************** - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._afm - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/docstring_api.rst b/doc/api/docstring_api.rst deleted file mode 100644 index 38a73a2e83d1..000000000000 --- a/doc/api/docstring_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -************************ -``matplotlib.docstring`` -************************ - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._docstring - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/index.rst b/doc/api/index.rst index 70c3b5343e7a..53f397a6817a 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -79,7 +79,6 @@ Alphabetical list of modules: :maxdepth: 1 matplotlib_configuration_api.rst - afm_api.rst animation_api.rst artist_api.rst axes_api.rst @@ -98,7 +97,6 @@ Alphabetical list of modules: container_api.rst contour_api.rst dates_api.rst - docstring_api.rst dviread.rst figure_api.rst font_manager_api.rst @@ -134,16 +132,18 @@ Alphabetical list of modules: text_api.rst texmanager_api.rst ticker_api.rst - tight_bbox_api.rst - tight_layout_api.rst transformations.rst tri_api.rst - type1font.rst typing_api.rst units_api.rst widgets_api.rst + _afm_api.rst _api_api.rst + _docstring_api.rst _enums_api.rst + _type1font.rst + _tight_bbox_api.rst + _tight_layout_api.rst toolkits/mplot3d.rst toolkits/axes_grid1.rst toolkits/axisartist.rst diff --git a/doc/api/tight_bbox_api.rst b/doc/api/tight_bbox_api.rst deleted file mode 100644 index 9e8dd2fa66f9..000000000000 --- a/doc/api/tight_bbox_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -************************* -``matplotlib.tight_bbox`` -************************* - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._tight_bbox - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/tight_layout_api.rst b/doc/api/tight_layout_api.rst deleted file mode 100644 index 35f92e3ddced..000000000000 --- a/doc/api/tight_layout_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -*************************** -``matplotlib.tight_layout`` -*************************** - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._tight_layout - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/type1font.rst b/doc/api/type1font.rst deleted file mode 100644 index 00ef38f4d447..000000000000 --- a/doc/api/type1font.rst +++ /dev/null @@ -1,13 +0,0 @@ -************************ -``matplotlib.type1font`` -************************ - -.. attention:: - This module is considered internal. - - Its use is deprecated and it will be removed in a future version. - -.. automodule:: matplotlib._type1font - :members: - :undoc-members: - :show-inheritance: From 7b941c8a924c07215984810649ddee2a4ed51a7a Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 12 Sep 2024 05:28:44 -0400 Subject: [PATCH 17/49] Backport PR #28805: add brackets to satisfy the new sequence requirement --- galleries/examples/animation/frame_grabbing_sgskip.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/galleries/examples/animation/frame_grabbing_sgskip.py b/galleries/examples/animation/frame_grabbing_sgskip.py index 08155d2c61a7..dcc2ca01afd9 100644 --- a/galleries/examples/animation/frame_grabbing_sgskip.py +++ b/galleries/examples/animation/frame_grabbing_sgskip.py @@ -6,8 +6,6 @@ Use a MovieWriter directly to grab individual frames and write them to a file. This avoids any event loop integration, and thus works even with the Agg backend. This is not recommended for use in an interactive setting. - -Output generated via `matplotlib.animation.Animation.to_jshtml`. """ import numpy as np @@ -39,5 +37,5 @@ for i in range(100): x0 += 0.1 * np.random.randn() y0 += 0.1 * np.random.randn() - l.set_data(x0, y0) + l.set_data([x0], [y0]) writer.grab_frame() From 96654d64dfea78901c9d912aca62c47fd4fb287c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 12 Sep 2024 05:28:44 -0400 Subject: [PATCH 18/49] Backport PR #28805: add brackets to satisfy the new sequence requirement --- galleries/examples/animation/frame_grabbing_sgskip.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/galleries/examples/animation/frame_grabbing_sgskip.py b/galleries/examples/animation/frame_grabbing_sgskip.py index 08155d2c61a7..dcc2ca01afd9 100644 --- a/galleries/examples/animation/frame_grabbing_sgskip.py +++ b/galleries/examples/animation/frame_grabbing_sgskip.py @@ -6,8 +6,6 @@ Use a MovieWriter directly to grab individual frames and write them to a file. This avoids any event loop integration, and thus works even with the Agg backend. This is not recommended for use in an interactive setting. - -Output generated via `matplotlib.animation.Animation.to_jshtml`. """ import numpy as np @@ -39,5 +37,5 @@ for i in range(100): x0 += 0.1 * np.random.randn() y0 += 0.1 * np.random.randn() - l.set_data(x0, y0) + l.set_data([x0], [y0]) writer.grab_frame() From 5fa2a000e4700294a059212dc3e0847e0db5ea01 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 12 Sep 2024 19:05:23 -0400 Subject: [PATCH 19/49] Backport PR #28810: Document how to obtain sans-serif usetex math. --- galleries/users_explain/text/usetex.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/galleries/users_explain/text/usetex.py b/galleries/users_explain/text/usetex.py index 0194a0030d48..f0c266819897 100644 --- a/galleries/users_explain/text/usetex.py +++ b/galleries/users_explain/text/usetex.py @@ -102,6 +102,12 @@ :rc:`text.usetex`. As noted above, underscores (``_``) do not require escaping outside of math mode. +.. note:: + LaTeX always defaults to using a serif font for math (even when + ``rcParams["font.family"] = "sans-serif"``). If desired, adding + ``\usepackage{sfmath}`` to ``rcParams["text.latex.preamble"]`` lets LaTeX + output sans-serif math. + PostScript options ================== @@ -129,19 +135,13 @@ :ref:`setting-windows-environment-variables` for details. * Using MiKTeX with Computer Modern fonts, if you get odd \*Agg and PNG - results, go to MiKTeX/Options and update your format files + results, go to MiKTeX/Options and update your format files. * On Ubuntu and Gentoo, the base texlive install does not ship with the type1cm package. You may need to install some of the extra packages to get all the goodies that come bundled with other LaTeX distributions. -* Some progress has been made so Matplotlib uses the dvi files - directly for text layout. This allows LaTeX to be used for text - layout with the pdf and svg backends, as well as the \*Agg and PS - backends. In the future, a LaTeX installation may be the only - external dependency. - .. _usetex-troubleshooting: Troubleshooting @@ -150,7 +150,7 @@ * Try deleting your :file:`.matplotlib/tex.cache` directory. If you don't know where to find :file:`.matplotlib`, see :ref:`locating-matplotlib-config-dir`. -* Make sure LaTeX, dvipng and ghostscript are each working and on your +* Make sure LaTeX, dvipng and Ghostscript are each working and on your :envvar:`PATH`. * Make sure what you are trying to do is possible in a LaTeX document, @@ -159,8 +159,7 @@ * :rc:`text.latex.preamble` is not officially supported. This option provides lots of flexibility, and lots of ways to cause - problems. Please disable this option before reporting problems to - the mailing list. + problems. Please disable this option before reporting problems. * If you still need help, please see :ref:`reporting-problems`. From a058fae22f55154bd4080b41a5d9b096e8e96d1d Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 12 Sep 2024 19:05:23 -0400 Subject: [PATCH 20/49] Backport PR #28810: Document how to obtain sans-serif usetex math. --- galleries/users_explain/text/usetex.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/galleries/users_explain/text/usetex.py b/galleries/users_explain/text/usetex.py index 0194a0030d48..f0c266819897 100644 --- a/galleries/users_explain/text/usetex.py +++ b/galleries/users_explain/text/usetex.py @@ -102,6 +102,12 @@ :rc:`text.usetex`. As noted above, underscores (``_``) do not require escaping outside of math mode. +.. note:: + LaTeX always defaults to using a serif font for math (even when + ``rcParams["font.family"] = "sans-serif"``). If desired, adding + ``\usepackage{sfmath}`` to ``rcParams["text.latex.preamble"]`` lets LaTeX + output sans-serif math. + PostScript options ================== @@ -129,19 +135,13 @@ :ref:`setting-windows-environment-variables` for details. * Using MiKTeX with Computer Modern fonts, if you get odd \*Agg and PNG - results, go to MiKTeX/Options and update your format files + results, go to MiKTeX/Options and update your format files. * On Ubuntu and Gentoo, the base texlive install does not ship with the type1cm package. You may need to install some of the extra packages to get all the goodies that come bundled with other LaTeX distributions. -* Some progress has been made so Matplotlib uses the dvi files - directly for text layout. This allows LaTeX to be used for text - layout with the pdf and svg backends, as well as the \*Agg and PS - backends. In the future, a LaTeX installation may be the only - external dependency. - .. _usetex-troubleshooting: Troubleshooting @@ -150,7 +150,7 @@ * Try deleting your :file:`.matplotlib/tex.cache` directory. If you don't know where to find :file:`.matplotlib`, see :ref:`locating-matplotlib-config-dir`. -* Make sure LaTeX, dvipng and ghostscript are each working and on your +* Make sure LaTeX, dvipng and Ghostscript are each working and on your :envvar:`PATH`. * Make sure what you are trying to do is possible in a LaTeX document, @@ -159,8 +159,7 @@ * :rc:`text.latex.preamble` is not officially supported. This option provides lots of flexibility, and lots of ways to cause - problems. Please disable this option before reporting problems to - the mailing list. + problems. Please disable this option before reporting problems. * If you still need help, please see :ref:`reporting-problems`. From 791d6c02c6a43b91ea2953910e6d20b9adffa612 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 16 Sep 2024 14:39:29 -0400 Subject: [PATCH 21/49] Backport PR #28818: Resolve configdir so that it's not a symlink when is_dir() is called --- lib/matplotlib/__init__.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 9e9325a27d73..ad4676b11ae0 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -518,35 +518,38 @@ def _get_xdg_cache_dir(): def _get_config_or_cache_dir(xdg_base_getter): configdir = os.environ.get('MPLCONFIGDIR') if configdir: - configdir = Path(configdir).resolve() + configdir = Path(configdir) elif sys.platform.startswith(('linux', 'freebsd')): # Only call _xdg_base_getter here so that MPLCONFIGDIR is tried first, # as _xdg_base_getter can throw. configdir = Path(xdg_base_getter(), "matplotlib") else: configdir = Path.home() / ".matplotlib" + # Resolve the path to handle potential issues with inaccessible symlinks. + configdir = configdir.resolve() try: configdir.mkdir(parents=True, exist_ok=True) - except OSError: - pass + except OSError as exc: + _log.warning("mkdir -p failed for path %s: %s", configdir, exc) else: if os.access(str(configdir), os.W_OK) and configdir.is_dir(): return str(configdir) + _log.warning("%s is not a writable directory", configdir) # If the config or cache directory cannot be created or is not a writable # directory, create a temporary one. try: tmpdir = tempfile.mkdtemp(prefix="matplotlib-") except OSError as exc: raise OSError( - f"Matplotlib requires access to a writable cache directory, but the " - f"default path ({configdir}) is not a writable directory, and a temporary " + f"Matplotlib requires access to a writable cache directory, but there " + f"was an issue with the default path ({configdir}), and a temporary " f"directory could not be created; set the MPLCONFIGDIR environment " f"variable to a writable directory") from exc os.environ["MPLCONFIGDIR"] = tmpdir atexit.register(shutil.rmtree, tmpdir) _log.warning( - "Matplotlib created a temporary cache directory at %s because the default path " - "(%s) is not a writable directory; it is highly recommended to set the " + "Matplotlib created a temporary cache directory at %s because there was " + "an issue with the default path (%s); it is highly recommended to set the " "MPLCONFIGDIR environment variable to a writable directory, in particular to " "speed up the import of Matplotlib and to better support multiprocessing.", tmpdir, configdir) From ae85b62e623baffa6679f9f3a58384ba0e1e5947 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 18 Sep 2024 22:36:21 -0400 Subject: [PATCH 22/49] Backport PR #28836: MNT: Use __init__ parameters of font properties --- .../text_labels_and_annotations/fonts_demo.py | 17 +++++------------ galleries/users_explain/text/text_intro.py | 5 +---- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/galleries/examples/text_labels_and_annotations/fonts_demo.py b/galleries/examples/text_labels_and_annotations/fonts_demo.py index bc36c10bce8b..821ee278c4ba 100644 --- a/galleries/examples/text_labels_and_annotations/fonts_demo.py +++ b/galleries/examples/text_labels_and_annotations/fonts_demo.py @@ -21,34 +21,28 @@ fig.text(0.1, 0.9, 'family', fontproperties=heading_font, **alignment) families = ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'] for k, family in enumerate(families): - font = FontProperties() - font.set_family(family) + font = FontProperties(family=[family]) fig.text(0.1, yp[k], family, fontproperties=font, **alignment) # Show style options styles = ['normal', 'italic', 'oblique'] fig.text(0.3, 0.9, 'style', fontproperties=heading_font, **alignment) for k, style in enumerate(styles): - font = FontProperties() - font.set_family('sans-serif') - font.set_style(style) + font = FontProperties(family='sans-serif', style=style) fig.text(0.3, yp[k], style, fontproperties=font, **alignment) # Show variant options variants = ['normal', 'small-caps'] fig.text(0.5, 0.9, 'variant', fontproperties=heading_font, **alignment) for k, variant in enumerate(variants): - font = FontProperties() - font.set_family('serif') - font.set_variant(variant) + font = FontProperties(family='serif', variant=variant) fig.text(0.5, yp[k], variant, fontproperties=font, **alignment) # Show weight options weights = ['light', 'normal', 'medium', 'semibold', 'bold', 'heavy', 'black'] fig.text(0.7, 0.9, 'weight', fontproperties=heading_font, **alignment) for k, weight in enumerate(weights): - font = FontProperties() - font.set_weight(weight) + font = FontProperties(weight=weight) fig.text(0.7, yp[k], weight, fontproperties=font, **alignment) # Show size options @@ -56,8 +50,7 @@ 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'] fig.text(0.9, 0.9, 'size', fontproperties=heading_font, **alignment) for k, size in enumerate(sizes): - font = FontProperties() - font.set_size(size) + font = FontProperties(size=size) fig.text(0.9, yp[k], size, fontproperties=font, **alignment) # Show bold italic diff --git a/galleries/users_explain/text/text_intro.py b/galleries/users_explain/text/text_intro.py index 948545667fa9..3b8a66f1c98e 100644 --- a/galleries/users_explain/text/text_intro.py +++ b/galleries/users_explain/text/text_intro.py @@ -177,10 +177,7 @@ from matplotlib.font_manager import FontProperties -font = FontProperties() -font.set_family('serif') -font.set_name('Times New Roman') -font.set_style('italic') +font = FontProperties(family='Times New Roman', style='italic') fig, ax = plt.subplots(figsize=(5, 3)) fig.subplots_adjust(bottom=0.15, left=0.2) From 172624ebcbdccb08b27fb137910a2253871801e1 Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Sat, 21 Sep 2024 08:31:41 +0100 Subject: [PATCH 23/49] Backport PR #28858: Fix flaky labelcolor tests --- lib/matplotlib/tests/test_legend.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index 0353f1408b73..3c2af275649f 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -868,8 +868,8 @@ def test_legend_pathcollection_labelcolor_linecolor_iterable(): # test the labelcolor for labelcolor='linecolor' on PathCollection # with iterable colors fig, ax = plt.subplots() - colors = np.random.default_rng().choice(['r', 'g', 'b'], 10) - ax.scatter(np.arange(10), np.arange(10)*1, label='#1', c=colors) + colors = np.array(['r', 'g', 'b', 'c', 'm'] * 2) + ax.scatter(np.arange(10), np.arange(10), label='#1', c=colors) leg = ax.legend(labelcolor='linecolor') text, = leg.get_texts() @@ -915,8 +915,8 @@ def test_legend_pathcollection_labelcolor_markeredgecolor_iterable(): # test the labelcolor for labelcolor='markeredgecolor' on PathCollection # with iterable colors fig, ax = plt.subplots() - colors = np.random.default_rng().choice(['r', 'g', 'b'], 10) - ax.scatter(np.arange(10), np.arange(10)*1, label='#1', edgecolor=colors) + colors = np.array(['r', 'g', 'b', 'c', 'm'] * 2) + ax.scatter(np.arange(10), np.arange(10), label='#1', edgecolor=colors) leg = ax.legend(labelcolor='markeredgecolor') for text, color in zip(leg.get_texts(), ['k']): @@ -970,8 +970,8 @@ def test_legend_pathcollection_labelcolor_markerfacecolor_iterable(): # test the labelcolor for labelcolor='markerfacecolor' on PathCollection # with iterable colors fig, ax = plt.subplots() - colors = np.random.default_rng().choice(['r', 'g', 'b'], 10) - ax.scatter(np.arange(10), np.arange(10)*1, label='#1', facecolor=colors) + colors = np.array(['r', 'g', 'b', 'c', 'm'] * 2) + ax.scatter(np.arange(10), np.arange(10), label='#1', facecolor=colors) leg = ax.legend(labelcolor='markerfacecolor') for text, color in zip(leg.get_texts(), ['k']): From ff3e448f0d7183d04c4e353fcb19948e88e5d31f Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:44:15 +0200 Subject: [PATCH 24/49] Backport PR #28883: Only check X11 when running Tkinter tests --- lib/matplotlib/_c_internal_utils.pyi | 1 + lib/matplotlib/cbook.py | 2 +- lib/matplotlib/tests/test_backend_tk.py | 4 +-- .../tests/test_backends_interactive.py | 10 +++++--- lib/matplotlib/tests/test_rcparams.py | 2 +- src/_c_internal_utils.cpp | 25 ++++++++++++++++++- 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/_c_internal_utils.pyi b/lib/matplotlib/_c_internal_utils.pyi index 3efc81bc8332..ccc172cde27a 100644 --- a/lib/matplotlib/_c_internal_utils.pyi +++ b/lib/matplotlib/_c_internal_utils.pyi @@ -1,4 +1,5 @@ def display_is_valid() -> bool: ... +def xdisplay_is_valid() -> bool: ... def Win32_GetForegroundWindow() -> int | None: ... def Win32_SetForegroundWindow(hwnd: int) -> None: ... diff --git a/lib/matplotlib/cbook.py b/lib/matplotlib/cbook.py index f5a4199cf9ad..c5b851ff6c9b 100644 --- a/lib/matplotlib/cbook.py +++ b/lib/matplotlib/cbook.py @@ -72,7 +72,7 @@ def _get_running_interactive_framework(): if frame.f_code in codes: return "tk" frame = frame.f_back - # premetively break reference cycle between locals and the frame + # Preemptively break reference cycle between locals and the frame. del frame macosx = sys.modules.get("matplotlib.backends._macosx") if macosx and macosx.event_loop_is_running(): diff --git a/lib/matplotlib/tests/test_backend_tk.py b/lib/matplotlib/tests/test_backend_tk.py index ee20a94042f7..89782e8a66f3 100644 --- a/lib/matplotlib/tests/test_backend_tk.py +++ b/lib/matplotlib/tests/test_backend_tk.py @@ -35,8 +35,8 @@ def _isolated_tk_test(success_count, func=None): reason="missing tkinter" ) @pytest.mark.skipif( - sys.platform == "linux" and not _c_internal_utils.display_is_valid(), - reason="$DISPLAY and $WAYLAND_DISPLAY are unset" + sys.platform == "linux" and not _c_internal_utils.xdisplay_is_valid(), + reason="$DISPLAY is unset" ) @pytest.mark.xfail( # https://github.com/actions/setup-python/issues/649 ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py index 2c6b61a48438..ca702bc1d99c 100644 --- a/lib/matplotlib/tests/test_backends_interactive.py +++ b/lib/matplotlib/tests/test_backends_interactive.py @@ -57,6 +57,8 @@ def wait_for(self, terminator): def _get_available_interactive_backends(): _is_linux_and_display_invalid = (sys.platform == "linux" and not _c_internal_utils.display_is_valid()) + _is_linux_and_xdisplay_invalid = (sys.platform == "linux" and + not _c_internal_utils.xdisplay_is_valid()) envs = [] for deps, env in [ *[([qt_api], @@ -74,10 +76,12 @@ def _get_available_interactive_backends(): ]: reason = None missing = [dep for dep in deps if not importlib.util.find_spec(dep)] - if _is_linux_and_display_invalid: - reason = "$DISPLAY and $WAYLAND_DISPLAY are unset" - elif missing: + if missing: reason = "{} cannot be imported".format(", ".join(missing)) + elif env["MPLBACKEND"] == "tkagg" and _is_linux_and_xdisplay_invalid: + reason = "$DISPLAY is unset" + elif _is_linux_and_display_invalid: + reason = "$DISPLAY and $WAYLAND_DISPLAY are unset" elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'): reason = "macosx backend fails on Azure" elif env["MPLBACKEND"].startswith('gtk'): diff --git a/lib/matplotlib/tests/test_rcparams.py b/lib/matplotlib/tests/test_rcparams.py index 4823df0ce250..25ae258ffcbb 100644 --- a/lib/matplotlib/tests/test_rcparams.py +++ b/lib/matplotlib/tests/test_rcparams.py @@ -536,7 +536,7 @@ def test_backend_fallback_headless(tmp_path): @pytest.mark.skipif( - sys.platform == "linux" and not _c_internal_utils.display_is_valid(), + sys.platform == "linux" and not _c_internal_utils.xdisplay_is_valid(), reason="headless") def test_backend_fallback_headful(tmp_path): pytest.importorskip("tkinter") diff --git a/src/_c_internal_utils.cpp b/src/_c_internal_utils.cpp index 74bb97904f89..561cb303639c 100644 --- a/src/_c_internal_utils.cpp +++ b/src/_c_internal_utils.cpp @@ -33,7 +33,7 @@ namespace py = pybind11; using namespace pybind11::literals; static bool -mpl_display_is_valid(void) +mpl_xdisplay_is_valid(void) { #ifdef __linux__ void* libX11; @@ -57,6 +57,19 @@ mpl_display_is_valid(void) return true; } } + return false; +#else + return true; +#endif +} + +static bool +mpl_display_is_valid(void) +{ +#ifdef __linux__ + if (mpl_xdisplay_is_valid()) { + return true; + } void* libwayland_client; if (getenv("WAYLAND_DISPLAY") && (libwayland_client = dlopen("libwayland-client.so.0", RTLD_LAZY))) { @@ -194,6 +207,16 @@ PYBIND11_MODULE(_c_internal_utils, m) succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL) succeeds. + On other platforms, always returns True.)"""); + m.def( + "xdisplay_is_valid", &mpl_xdisplay_is_valid, + R"""( -- + Check whether the current X11 display is valid. + + On Linux, returns True if either $DISPLAY is set and XOpenDisplay(NULL) + succeeds. Use this function if you need to specifically check for X11 + only (e.g., for Tkinter). + On other platforms, always returns True.)"""); m.def( "Win32_GetCurrentProcessExplicitAppUserModelID", From 00f63b745f453f5e736b62d978df95ac9ee68f6b Mon Sep 17 00:00:00 2001 From: Kyra Cho Date: Fri, 27 Sep 2024 16:55:12 -0700 Subject: [PATCH 25/49] Backport PR #28881: Fix `axline` for slopes <= 1E-8. Closes #28386 --- lib/matplotlib/lines.py | 2 +- lib/matplotlib/tests/test_lines.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index 72e74f4eb9c5..569669f76e8d 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -1520,7 +1520,7 @@ def get_transform(self): (vxlo, vylo), (vxhi, vyhi) = ax.transScale.transform(ax.viewLim) # General case: find intersections with view limits in either # direction, and draw between the middle two points. - if np.isclose(slope, 0): + if slope == 0: start = vxlo, y1 stop = vxhi, y1 elif np.isinf(slope): diff --git a/lib/matplotlib/tests/test_lines.py b/lib/matplotlib/tests/test_lines.py index 531237b2ba28..902b7aa2c02d 100644 --- a/lib/matplotlib/tests/test_lines.py +++ b/lib/matplotlib/tests/test_lines.py @@ -436,3 +436,14 @@ def test_axline_setters(): with pytest.raises(ValueError, match="Cannot set a 'slope' value while 'xy2' is set"): line2.set_slope(3) + + +def test_axline_small_slope(): + """Test that small slopes are not coerced to zero in the transform.""" + line = plt.axline((0, 0), slope=1e-14) + p1 = line.get_transform().transform_point((0, 0)) + p2 = line.get_transform().transform_point((1, 1)) + # y-values must be slightly different + dy = p2[1] - p1[1] + assert dy > 0 + assert dy < 4e-12 From ab09fcc97c9ad791ba41dcfdd4276f634585263a Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:36:36 +0200 Subject: [PATCH 26/49] Backport PR #28689: ci: Enable testing on Python 3.13 --- .github/workflows/tests.yml | 54 +++++++++++++++++-- lib/matplotlib/tests/test_axes.py | 4 +- lib/matplotlib/tests/test_contour.py | 2 +- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 2 +- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 634c83fa57fd..cd4c08e29fb9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -88,14 +88,31 @@ jobs: pyqt6-ver: '!=6.6.0' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' - - os: macos-12 # This runnre is on Intel chips. - python-version: 3.9 + - os: ubuntu-22.04 + python-version: '3.13' + # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html + pyqt6-ver: '!=6.6.0' + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 + pyside6-ver: '!=6.5.1' + - name-suffix: "Free-threaded" + os: ubuntu-22.04 + python-version: '3.13t' + # https://www.riverbankcomputing.com/pipermail/pyqt/2023-November/045606.html + pyqt6-ver: '!=6.6.0' + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 + pyside6-ver: '!=6.5.1' + - os: macos-12 # This runner is on Intel chips. + python-version: '3.9' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' - os: macos-14 # This runner is on M1 (arm64) chips. python-version: '3.12' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' + - os: macos-14 # This runner is on M1 (arm64) chips. + python-version: '3.13' + # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 + pyside6-ver: '!=6.5.1' steps: - uses: actions/checkout@v4 @@ -104,8 +121,17 @@ jobs: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 + if: matrix.python-version != '3.13t' with: python-version: ${{ matrix.python-version }} + allow-prereleases: true + + - name: Set up Python ${{ matrix.python-version }} + uses: deadsnakes/action@6c8b9b82fe0b4344f4b98f2775fcc395df45e494 # v3.1.0 + if: matrix.python-version == '3.13t' + with: + python-version: '3.13' + nogil: true - name: Install OS dependencies run: | @@ -152,6 +178,11 @@ jobs: texlive-luatex \ texlive-pictures \ texlive-xetex + if [[ "${{ matrix.python-version }}" = '3.13t' ]]; then + # TODO: Remove this once setup-python supports nogil distributions. + sudo apt-get install -yy --no-install-recommends \ + python3.13-tk-nogil + fi if [[ "${{ matrix.os }}" = ubuntu-20.04 ]]; then sudo apt-get install -yy --no-install-recommends libopengl0 else # ubuntu-22.04 @@ -202,6 +233,15 @@ jobs: 4-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}- 4-${{ runner.os }}-py${{ matrix.python-version }}-mpl- + - name: Install the nightly dependencies + if: matrix.python-version == '3.13t' + run: | + python -m pip install pytz tzdata python-dateutil # Must be installed for Pandas. + python -m pip install \ + --pre \ + --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \ + --upgrade --only-binary=:all: numpy pandas pillow contourpy + - name: Install Python dependencies run: | # Upgrade pip and setuptools and wheel to get as clean an install as @@ -227,6 +267,7 @@ jobs: # Sphinx is needed to run sphinxext tests python -m pip install --upgrade sphinx!=6.1.2 + if [[ "${{ matrix.python-version }}" != '3.13t' ]]; then # GUI toolkits are pip-installable only for some versions of Python # so don't fail if we can't install them. Make it easier to check # whether the install was successful by trying to import the toolkit @@ -246,11 +287,11 @@ jobs: python -c 'import PyQt5.QtCore' && echo 'PyQt5 is available' || echo 'PyQt5 is not available' - # Even though PySide2 wheels can be installed on Python 3.12, they are broken and since PySide2 is + # Even though PySide2 wheels can be installed on Python 3.12+, they are broken and since PySide2 is # deprecated, they are unlikely to be fixed. For the same deprecation reason, there are no wheels # on M1 macOS, so don't bother there either. if [[ "${{ matrix.os }}" != 'macos-14' - && "${{ matrix.python-version }}" != '3.12' ]]; then + && "${{ matrix.python-version }}" != '3.12' && "${{ matrix.python-version }}" != '3.13' ]]; then python -mpip install --upgrade pyside2${{ matrix.pyside2-ver }} && python -c 'import PySide2.QtCore' && echo 'PySide2 is available' || @@ -272,6 +313,8 @@ jobs: echo 'wxPython is available' || echo 'wxPython is not available' + fi # Skip backends on Python 3.13t. + - name: Install the nightly dependencies # Only install the nightly dependencies during the scheduled event if: github.event_name == 'schedule' && matrix.name-suffix != '(Minimum Versions)' @@ -310,6 +353,9 @@ jobs: - name: Run pytest run: | + if [[ "${{ matrix.python-version }}" == '3.13t' ]]; then + export PYTHON_GIL=0 + fi pytest -rfEsXR -n auto \ --maxfail=50 --timeout=300 --durations=25 \ --cov-report=xml --cov=lib --log-level=DEBUG --color=yes diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 3ec9923c0840..e99ef129eb9a 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -1186,7 +1186,7 @@ def test_imshow(): @image_comparison( ['imshow_clip'], style='mpl20', - tol=1.24 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) + tol=1.24 if platform.machine() in ('aarch64', 'arm64', 'ppc64le', 's390x') else 0) def test_imshow_clip(): # As originally reported by Gellule Xg # use former defaults to match existing baseline image @@ -2570,7 +2570,7 @@ def test_contour_hatching(): @image_comparison( ['contour_colorbar'], style='mpl20', - tol=0.54 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) + tol=0.54 if platform.machine() in ('aarch64', 'arm64', 'ppc64le', 's390x') else 0) def test_contour_colorbar(): x, y, z = contour_dat() diff --git a/lib/matplotlib/tests/test_contour.py b/lib/matplotlib/tests/test_contour.py index d4600a14fe1c..0622c099a20c 100644 --- a/lib/matplotlib/tests/test_contour.py +++ b/lib/matplotlib/tests/test_contour.py @@ -442,7 +442,7 @@ def test_contourf_log_extension(split_collections): @pytest.mark.parametrize("split_collections", [False, True]) @image_comparison( ['contour_addlines.png'], remove_text=True, style='mpl20', - tol=0.15 if platform.machine() in ('aarch64', 'ppc64le', 's390x') + tol=0.15 if platform.machine() in ('aarch64', 'arm64', 'ppc64le', 's390x') else 0.03) # tolerance is because image changed minutely when tick finding on # colorbars was cleaned up... diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index ecb51b724c27..ff5ab230ef06 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -221,7 +221,7 @@ def test_bar3d_lightsource(): @mpl3d_image_comparison( ['contour3d.png'], style='mpl20', - tol=0.002 if platform.machine() in ('aarch64', 'ppc64le', 's390x') else 0) + tol=0.002 if platform.machine() in ('aarch64', 'arm64', 'ppc64le', 's390x') else 0) def test_contour3d(): plt.rcParams['axes3d.automargin'] = True # Remove when image is regenerated fig = plt.figure() From fad3579287324c16daeb8719af68ccb58fe1b94b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 4 Oct 2024 05:02:26 -0400 Subject: [PATCH 27/49] Backport PR #28900: DOC: Improve fancybox demo --- .../shapes_and_collections/fancybox_demo.py | 84 ++++++++++++++----- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/galleries/examples/shapes_and_collections/fancybox_demo.py b/galleries/examples/shapes_and_collections/fancybox_demo.py index 91cc1d1749ea..8d36a5a14d9d 100644 --- a/galleries/examples/shapes_and_collections/fancybox_demo.py +++ b/galleries/examples/shapes_and_collections/fancybox_demo.py @@ -3,7 +3,8 @@ Drawing fancy boxes =================== -The following examples show how to plot boxes with different visual properties. +The following examples show how to plot boxes (`.FancyBboxPatch`) with different +visual properties. """ import inspect @@ -15,7 +16,12 @@ import matplotlib.transforms as mtransforms # %% -# First we'll show some sample boxes with fancybox. +# Box styles +# ---------- +# `.FancyBboxPatch` supports different `.BoxStyle`\s. Note that `~.Axes.text` +# allows to draw a box around the text by adding the ``bbox`` parameter. Therefore, +# you don't see explicit `.FancyBboxPatch` and `.BoxStyle` calls in the following +# example. styles = mpatch.BoxStyle.get_styles() ncol = 2 @@ -41,13 +47,21 @@ # %% -# Next we'll show off multiple fancy boxes at once. - +# Parameters for modifying the box +# -------------------------------- +# `.BoxStyle`\s have additional parameters to configure their appearance. +# For example, "round" boxes can have ``pad`` and ``rounding``. +# +# Additionally, the `.FancyBboxPatch` parameters ``mutation_scale`` and +# ``mutation_aspect`` scale the box appearance. def add_fancy_patch_around(ax, bb, **kwargs): - fancy = FancyBboxPatch(bb.p0, bb.width, bb.height, - fc=(1, 0.8, 1, 0.5), ec=(1, 0.5, 1, 0.5), - **kwargs) + kwargs = { + 'facecolor': (1, 0.8, 1, 0.5), + 'edgecolor': (1, 0.5, 1, 0.5), + **kwargs + } + fancy = FancyBboxPatch(bb.p0, bb.width, bb.height, **kwargs) ax.add_patch(fancy) return fancy @@ -65,7 +79,7 @@ def draw_control_points_for_patches(ax): ax = axs[0, 0] # a fancy box with round corners. pad=0.1 -fancy = add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1") +add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1") ax.set(xlim=(0, 1), ylim=(0, 1), aspect=1, title='boxstyle="round,pad=0.1"') @@ -84,33 +98,61 @@ def draw_control_points_for_patches(ax): ax = axs[1, 0] # mutation_scale determines the overall scale of the mutation, i.e. both pad # and rounding_size is scaled according to this value. -fancy = add_fancy_patch_around( - ax, bb, boxstyle="round,pad=0.1", mutation_scale=2) +add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1", mutation_scale=2) ax.set(xlim=(0, 1), ylim=(0, 1), aspect=1, title='boxstyle="round,pad=0.1"\n mutation_scale=2') ax = axs[1, 1] -# When the aspect ratio of the Axes is not 1, the fancy box may not be what you -# expected (green). -fancy = add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.2") -fancy.set(facecolor="none", edgecolor="green") -# You can compensate this by setting the mutation_aspect (pink). -fancy = add_fancy_patch_around( - ax, bb, boxstyle="round,pad=0.3", mutation_aspect=0.5) -ax.set(xlim=(-.5, 1.5), ylim=(0, 1), aspect=2, - title='boxstyle="round,pad=0.3"\nmutation_aspect=.5') +# mutation_aspect scales the vertical influence of the parameters (technically, +# it scales the height of the box down by mutation_aspect, applies the box parameters +# and scales the result back up). In effect, the vertical pad is scaled to +# pad * mutation_aspect, e.g. mutation_aspect=0.5 halves the vertical pad. +add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1", mutation_aspect=0.5) +ax.set(xlim=(0, 1), ylim=(0, 1), + title='boxstyle="round,pad=0.1"\nmutation_aspect=0.5') for ax in axs.flat: draw_control_points_for_patches(ax) # Draw the original bbox (using boxstyle=square with pad=0). - fancy = add_fancy_patch_around(ax, bb, boxstyle="square,pad=0") - fancy.set(edgecolor="black", facecolor="none", zorder=10) + add_fancy_patch_around(ax, bb, boxstyle="square,pad=0", + edgecolor="black", facecolor="none", zorder=10) fig.tight_layout() plt.show() +# %% +# Creating visually constant padding on non-equal aspect Axes +# ----------------------------------------------------------- +# Since padding is in box coordinates, i.e. usually data coordinates, +# a given padding is rendered to different visual sizes if the +# Axes aspect is not 1. +# To get visually equal vertical and horizontal padding, set the +# mutation_aspect to the inverse of the Axes aspect. This scales +# the vertical padding appropriately. + +fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6.5, 5)) + +# original boxes +bb = mtransforms.Bbox([[-0.5, -0.5], [0.5, 0.5]]) +add_fancy_patch_around(ax1, bb, boxstyle="square,pad=0", + edgecolor="black", facecolor="none", zorder=10) +add_fancy_patch_around(ax2, bb, boxstyle="square,pad=0", + edgecolor="black", facecolor="none", zorder=10) +ax1.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), aspect=2) +ax2.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), aspect=2) + + +fancy = add_fancy_patch_around( + ax1, bb, boxstyle="round,pad=0.5") +ax1.set_title("aspect=2\nmutation_aspect=1") + +fancy = add_fancy_patch_around( + ax2, bb, boxstyle="round,pad=0.5", mutation_aspect=0.5) +ax2.set_title("aspect=2\nmutation_aspect=0.5") + + # %% # # .. admonition:: References From 97ea6ef94d0e67271fda0853b55aaf8c077ae4df Mon Sep 17 00:00:00 2001 From: "Lumberbot (aka Jack)" <39504233+meeseeksmachine@users.noreply.github.com> Date: Wed, 9 Oct 2024 12:07:04 -0700 Subject: [PATCH 28/49] Backport PR #28952: BLD: update trove metadata to support py3.13 (#28954) Co-authored-by: Greg Lucas --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 891ef87e4342..c0237c7df5c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ classifiers=[ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: Visualization", ] From 7fd3b7ba4aae22d6defd14d1cbb69e562d7f4522 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:04:14 +0200 Subject: [PATCH 29/49] Backport PR #28987: Fix: Do not use numeric tolerances for axline special cases --- lib/matplotlib/lines.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index 569669f76e8d..d24e528e4c0a 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -1505,8 +1505,8 @@ def get_transform(self): points_transform.transform([self._xy1, self._xy2]) dx = x2 - x1 dy = y2 - y1 - if np.allclose(x1, x2): - if np.allclose(y1, y2): + if dx == 0: + if dy == 0: raise ValueError( f"Cannot draw a line through two identical points " f"(x={(x1, x2)}, y={(y1, y2)})") From c2116dea25226d756b55e55489a53f73b89cdf97 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 17 Oct 2024 15:07:00 -0400 Subject: [PATCH 30/49] Backport PR #28972: Switch macOS 12 runner images to macOS 13 --- .github/workflows/cibuildwheel.yml | 2 +- .github/workflows/tests.yml | 13 ++++++++++++- azure-pipelines.yml | 11 +++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cibuildwheel.yml b/.github/workflows/cibuildwheel.yml index 9de63b14c4fd..a145b5bbcc08 100644 --- a/.github/workflows/cibuildwheel.yml +++ b/.github/workflows/cibuildwheel.yml @@ -124,7 +124,7 @@ jobs: cibw_archs: "aarch64" - os: windows-latest cibw_archs: "auto64" - - os: macos-12 + - os: macos-13 cibw_archs: "x86_64" - os: macos-14 cibw_archs: "arm64" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cd4c08e29fb9..4100fda43a36 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -101,7 +101,7 @@ jobs: pyqt6-ver: '!=6.6.0' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' - - os: macos-12 # This runner is on Intel chips. + - os: macos-13 # This runner is on Intel chips. python-version: '3.9' # https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2346 pyside6-ver: '!=6.5.1' @@ -192,6 +192,17 @@ jobs: ;; macOS) brew update + # Periodically, Homebrew updates Python and fails to overwrite the + # existing not-managed-by-Homebrew copy without explicitly being told + # to do so. GitHub/Azure continues to avoid fixing their runner images: + # https://github.com/actions/runner-images/issues/9966 + # so force an overwrite even if there are no Python updates. + # We don't even care about Homebrew's Python because we use the one + # from actions/setup-python. + for python_package in $(brew list | grep python@); do + brew unlink ${python_package} + brew link --overwrite ${python_package} + done brew install ccache ghostscript gobject-introspection gtk4 ninja brew install --cask font-noto-sans-cjk inkscape ;; diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4c50c543846a..e2829ce81e9f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -120,6 +120,17 @@ stages: ;; Darwin) brew update + # Periodically, Homebrew updates Python and fails to overwrite the + # existing not-managed-by-Homebrew copy without explicitly being told + # to do so. GitHub/Azure continues to avoid fixing their runner images: + # https://github.com/actions/runner-images/issues/9966 + # so force an overwrite even if there are no Python updates. + # We don't even care about Homebrew's Python because we use the one + # from UsePythonVersion. + for python_package in $(brew list | grep python@); do + brew unlink ${python_package} + brew link --overwrite ${python_package} + done brew install --cask xquartz brew install ccache ffmpeg imagemagick mplayer ninja pkg-config brew install --cask font-noto-sans-cjk-sc From 1f1901baa5ce5788eba5feb63ae12df2eac84975 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 7 Oct 2024 16:08:48 +0200 Subject: [PATCH 31/49] Backport PR #28925: TST: handle change in pytest.importorskip behavior --- lib/matplotlib/tests/test_rcparams.py | 8 +++++++- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/tests/test_rcparams.py b/lib/matplotlib/tests/test_rcparams.py index 25ae258ffcbb..0aa3ec0ba603 100644 --- a/lib/matplotlib/tests/test_rcparams.py +++ b/lib/matplotlib/tests/test_rcparams.py @@ -5,6 +5,7 @@ from unittest import mock from cycler import cycler, Cycler +from packaging.version import parse as parse_version import pytest import matplotlib as mpl @@ -539,7 +540,12 @@ def test_backend_fallback_headless(tmp_path): sys.platform == "linux" and not _c_internal_utils.xdisplay_is_valid(), reason="headless") def test_backend_fallback_headful(tmp_path): - pytest.importorskip("tkinter") + if parse_version(pytest.__version__) >= parse_version('8.2.0'): + pytest_kwargs = dict(exc_type=ImportError) + else: + pytest_kwargs = {} + + pytest.importorskip("tkinter", **pytest_kwargs) env = {**os.environ, "MPLBACKEND": "", "MPLCONFIGDIR": str(tmp_path)} backend = subprocess_run_for_testing( [sys.executable, "-c", diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index ff5ab230ef06..20b8dcd432db 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -1,6 +1,7 @@ import functools import itertools import platform +import sys import pytest @@ -114,7 +115,7 @@ def test_axes3d_repr(): @mpl3d_image_comparison(['axes3d_primary_views.png'], style='mpl20', - tol=0.05 if platform.machine() == "arm64" else 0) + tol=0.05 if sys.platform == "darwin" else 0) def test_axes3d_primary_views(): # (elev, azim, roll) views = [(90, -90, 0), # XY From 7b547eacebb0d854152e0e5d1afb3edc5da5ee4d Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Mon, 21 Oct 2024 22:09:44 +0100 Subject: [PATCH 32/49] Backport PR #28993: FIX: contourf hatches use multiple edgecolors --- lib/matplotlib/contour.py | 4 ++++ .../test_contour/contourf_hatch_colors.png | Bin 0 -> 19765 bytes lib/matplotlib/tests/test_contour.py | 8 ++++++++ 3 files changed, 12 insertions(+) create mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contourf_hatch_colors.png diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index 0e6068c64b62..3b2bf3843f4d 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -1415,12 +1415,16 @@ def draw(self, renderer): super().draw(renderer) return # In presence of hatching, draw contours one at a time. + edgecolors = self.get_edgecolors() + if edgecolors.size == 0: + edgecolors = ("none",) for idx in range(n_paths): with cbook._setattr_cm(self, _paths=[paths[idx]]), self._cm_set( hatch=self.hatches[idx % len(self.hatches)], array=[self.get_array()[idx]], linewidths=[self.get_linewidths()[idx % len(self.get_linewidths())]], linestyles=[self.get_linestyles()[idx % len(self.get_linestyles())]], + edgecolors=edgecolors[idx % len(edgecolors)], ): super().draw(renderer) diff --git a/lib/matplotlib/tests/baseline_images/test_contour/contourf_hatch_colors.png b/lib/matplotlib/tests/baseline_images/test_contour/contourf_hatch_colors.png new file mode 100644 index 0000000000000000000000000000000000000000..18d949773ded79b5e931e035032c7f0ee590cd6b GIT binary patch literal 19765 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 literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_contour.py b/lib/matplotlib/tests/test_contour.py index 0622c099a20c..a3e00c30ce97 100644 --- a/lib/matplotlib/tests/test_contour.py +++ b/lib/matplotlib/tests/test_contour.py @@ -198,6 +198,14 @@ def test_given_colors_levels_and_extends(split_collections): _maybe_split_collections(split_collections) +@image_comparison(['contourf_hatch_colors'], + remove_text=True, style='mpl20', extensions=['png']) +def test_hatch_colors(): + fig, ax = plt.subplots() + cf = ax.contourf([[0, 1], [1, 2]], hatches=['-', '/', '\\', '//'], cmap='gray') + cf.set_edgecolors(["blue", "grey", "yellow", "red"]) + + @pytest.mark.parametrize("split_collections", [False, True]) @image_comparison(['contour_log_locator.svg'], style='mpl20', remove_text=False) def test_log_locator_levels(split_collections): From 3cf5e95e1c98e5ab3ba955606b2bfd1aa324b911 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:24:26 +0200 Subject: [PATCH 33/49] Backport PR #29005: DOC: Update meson-python intersphinx link --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 8036edec9989..04f48204eb77 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -241,7 +241,7 @@ def _check_dependencies(): 'scipy': ('https://docs.scipy.org/doc/scipy/', None), 'tornado': ('https://www.tornadoweb.org/en/stable/', None), 'xarray': ('https://docs.xarray.dev/en/stable/', None), - 'meson-python': ('https://meson-python.readthedocs.io/en/stable/', None) + 'meson-python': ('https://mesonbuild.com/meson-python/', None), } From f3df3a16d1dce3770555d94a386b3f8587f8feba Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 24 Oct 2024 07:02:26 +0200 Subject: [PATCH 34/49] Backport PR #29014: FIX: fake out setuptools scm in tox on ci --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index cb2fcc979076..a4fbbd1793ff 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,8 @@ setenv = MPLCONFIGDIR={envtmpdir}/.matplotlib PIP_USER = 0 PIP_ISOLATED = 1 + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_MATPLOTLIB = 0.0.0 + usedevelop = True commands = pytest --pyargs matplotlib {posargs} From 5882c882d67ef134a6ad758f3f54cb43c25cb05b Mon Sep 17 00:00:00 2001 From: hannah Date: Mon, 28 Oct 2024 18:49:26 -0400 Subject: [PATCH 35/49] Backport PR #27569: DOC: initial tags for statistics section of gallery --- galleries/examples/statistics/boxplot.py | 2 ++ galleries/examples/statistics/boxplot_color.py | 2 ++ galleries/examples/statistics/boxplot_demo.py | 2 ++ galleries/examples/statistics/boxplot_vs_violin.py | 2 ++ galleries/examples/statistics/bxp.py | 2 ++ galleries/examples/statistics/confidence_ellipse.py | 8 ++++++++ galleries/examples/statistics/customized_violin.py | 2 ++ galleries/examples/statistics/errorbar.py | 3 +++ galleries/examples/statistics/errorbar_features.py | 2 ++ galleries/examples/statistics/errorbar_limits.py | 2 ++ galleries/examples/statistics/errorbars_and_boxes.py | 8 ++++++++ galleries/examples/statistics/hexbin_demo.py | 2 ++ galleries/examples/statistics/hist.py | 9 +++++++++ galleries/examples/statistics/histogram_bihistogram.py | 4 ++++ galleries/examples/statistics/histogram_cumulative.py | 2 ++ galleries/examples/statistics/histogram_histtypes.py | 2 ++ galleries/examples/statistics/histogram_multihist.py | 2 ++ galleries/examples/statistics/histogram_normalization.py | 2 ++ .../statistics/multiple_histograms_side_by_side.py | 7 +++++++ galleries/examples/statistics/time_series_histogram.py | 8 ++++++++ galleries/examples/statistics/violinplot.py | 2 ++ 21 files changed, 75 insertions(+) diff --git a/galleries/examples/statistics/boxplot.py b/galleries/examples/statistics/boxplot.py index ccdaab97d24a..6d30cbd4b5f0 100644 --- a/galleries/examples/statistics/boxplot.py +++ b/galleries/examples/statistics/boxplot.py @@ -97,6 +97,8 @@ # %% # +# .. tags:: plot-type: boxplot, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/boxplot_color.py b/galleries/examples/statistics/boxplot_color.py index 3491253aaf3e..acdb37d7d520 100644 --- a/galleries/examples/statistics/boxplot_color.py +++ b/galleries/examples/statistics/boxplot_color.py @@ -36,6 +36,8 @@ # %% # +# .. tags:: styling: color, domain: statistics, plot-type: boxplot +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/boxplot_demo.py b/galleries/examples/statistics/boxplot_demo.py index eca0e152078e..ec23408c0bfc 100644 --- a/galleries/examples/statistics/boxplot_demo.py +++ b/galleries/examples/statistics/boxplot_demo.py @@ -247,6 +247,8 @@ def fake_bootstrapper(n): # %% # +# .. tags:: domain: statistics, plot-type: boxplot +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/boxplot_vs_violin.py b/galleries/examples/statistics/boxplot_vs_violin.py index dce8912013b0..f277e737e65c 100644 --- a/galleries/examples/statistics/boxplot_vs_violin.py +++ b/galleries/examples/statistics/boxplot_vs_violin.py @@ -54,6 +54,8 @@ # %% # +# .. tags:: plot-type: violin, plot-type: boxplot, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/bxp.py b/galleries/examples/statistics/bxp.py index b12bfebd16cc..3ddd164df742 100644 --- a/galleries/examples/statistics/bxp.py +++ b/galleries/examples/statistics/bxp.py @@ -64,6 +64,8 @@ # %% # +# .. tags:: plot-type: speciality, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/confidence_ellipse.py b/galleries/examples/statistics/confidence_ellipse.py index 27b06146a44e..4ac0917f4bda 100644 --- a/galleries/examples/statistics/confidence_ellipse.py +++ b/galleries/examples/statistics/confidence_ellipse.py @@ -217,6 +217,14 @@ def get_correlated_dataset(n, dependency, mu, scale): # %% # +# .. tags:: +# +# plot-type: speciality +# plot-type: scatter +# component: ellipse +# component: patch +# domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/customized_violin.py b/galleries/examples/statistics/customized_violin.py index c1d2e432ca2e..29ddcda92fbe 100644 --- a/galleries/examples/statistics/customized_violin.py +++ b/galleries/examples/statistics/customized_violin.py @@ -73,6 +73,8 @@ def set_axis_style(ax, labels): # %% # +# .. tags:: plot-type: violin, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbar.py b/galleries/examples/statistics/errorbar.py index a25cadf88211..019590dc3f32 100644 --- a/galleries/examples/statistics/errorbar.py +++ b/galleries/examples/statistics/errorbar.py @@ -21,6 +21,9 @@ # %% # +# +# .. tags:: plot-type: errorbar, domain: statistics, +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbar_features.py b/galleries/examples/statistics/errorbar_features.py index 349cc89ff2e0..8abaffcda537 100644 --- a/galleries/examples/statistics/errorbar_features.py +++ b/galleries/examples/statistics/errorbar_features.py @@ -48,6 +48,8 @@ # %% # +# .. tags:: plot-type: errorbar, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbar_limits.py b/galleries/examples/statistics/errorbar_limits.py index d5b0e476d894..f1d26460d947 100644 --- a/galleries/examples/statistics/errorbar_limits.py +++ b/galleries/examples/statistics/errorbar_limits.py @@ -77,6 +77,8 @@ # %% # +# .. tags:: plot-type: errorbar, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbars_and_boxes.py b/galleries/examples/statistics/errorbars_and_boxes.py index 54c8786096c7..b45eee751137 100644 --- a/galleries/examples/statistics/errorbars_and_boxes.py +++ b/galleries/examples/statistics/errorbars_and_boxes.py @@ -71,6 +71,14 @@ def make_error_boxes(ax, xdata, ydata, xerror, yerror, facecolor='r', # %% # +# +# .. tags:: +# +# plot-type: errorbar +# component: rectangle +# component: patchcollection +# domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/hexbin_demo.py b/galleries/examples/statistics/hexbin_demo.py index b9a6206a934f..bd1522772aae 100644 --- a/galleries/examples/statistics/hexbin_demo.py +++ b/galleries/examples/statistics/hexbin_demo.py @@ -35,6 +35,8 @@ # %% # +# .. tags:: plot-type: histogram, plot-type: hexbin, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/hist.py b/galleries/examples/statistics/hist.py index 8b06093913df..e31aca0228c2 100644 --- a/galleries/examples/statistics/hist.py +++ b/galleries/examples/statistics/hist.py @@ -103,6 +103,15 @@ # %% # +# .. tags:: +# +# plot-type: histogram, +# plot-type: histogram2d +# domain: statistics +# styling: color, +# component: normalization +# component: patch +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_bihistogram.py b/galleries/examples/statistics/histogram_bihistogram.py index 7bfae14e9285..73f549493438 100644 --- a/galleries/examples/statistics/histogram_bihistogram.py +++ b/galleries/examples/statistics/histogram_bihistogram.py @@ -43,3 +43,7 @@ ax.legend() plt.show() + +# %% +# +# .. tags:: plot-type: histogram, domain: statistics, purpose: showcase diff --git a/galleries/examples/statistics/histogram_cumulative.py b/galleries/examples/statistics/histogram_cumulative.py index 9ce16568d126..d87305629f8d 100644 --- a/galleries/examples/statistics/histogram_cumulative.py +++ b/galleries/examples/statistics/histogram_cumulative.py @@ -67,6 +67,8 @@ # %% # +# .. tags:: plot-type: ecdf, plot-type: histogram, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_histtypes.py b/galleries/examples/statistics/histogram_histtypes.py index 0188d7bf5d0f..53d6425cf4dc 100644 --- a/galleries/examples/statistics/histogram_histtypes.py +++ b/galleries/examples/statistics/histogram_histtypes.py @@ -51,6 +51,8 @@ # %% # +# .. tags:: plot-type: histogram, domain: statistics, purpose: reference +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_multihist.py b/galleries/examples/statistics/histogram_multihist.py index f1957dc38939..78ff03719057 100644 --- a/galleries/examples/statistics/histogram_multihist.py +++ b/galleries/examples/statistics/histogram_multihist.py @@ -47,6 +47,8 @@ # %% # +# .. tags:: plot-type: histogram, domain: statistics, purpose: reference +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_normalization.py b/galleries/examples/statistics/histogram_normalization.py index 9418b7af002b..2c423edad208 100644 --- a/galleries/examples/statistics/histogram_normalization.py +++ b/galleries/examples/statistics/histogram_normalization.py @@ -243,6 +243,8 @@ # %% # +# .. tags:: plot-type: histogram, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/multiple_histograms_side_by_side.py b/galleries/examples/statistics/multiple_histograms_side_by_side.py index 3c5766f8e546..733aed51f253 100644 --- a/galleries/examples/statistics/multiple_histograms_side_by_side.py +++ b/galleries/examples/statistics/multiple_histograms_side_by_side.py @@ -63,6 +63,13 @@ # %% # +# .. tags:: +# +# domain: statistics +# plot-type: barh +# plot-type: histogram +# styling: position +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/time_series_histogram.py b/galleries/examples/statistics/time_series_histogram.py index 371d182915b8..6f9a543fb4e5 100644 --- a/galleries/examples/statistics/time_series_histogram.py +++ b/galleries/examples/statistics/time_series_histogram.py @@ -94,6 +94,14 @@ # %% # +# .. tags:: +# +# plot-type: histogram2d +# plot-type: pcolormesh +# purpose: storytelling +# styling: color +# component: colormap +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/violinplot.py b/galleries/examples/statistics/violinplot.py index afcc1c977034..3d0d44538032 100644 --- a/galleries/examples/statistics/violinplot.py +++ b/galleries/examples/statistics/violinplot.py @@ -106,6 +106,8 @@ # %% # +# .. tags:: plot-type: violin, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown From af21823d513c6c01d9b8037fa6c2e68ab90fedfe Mon Sep 17 00:00:00 2001 From: hannah Date: Mon, 28 Oct 2024 18:49:26 -0400 Subject: [PATCH 36/49] Backport PR #27569: DOC: initial tags for statistics section of gallery --- galleries/examples/statistics/boxplot.py | 2 ++ galleries/examples/statistics/boxplot_color.py | 2 ++ galleries/examples/statistics/boxplot_demo.py | 2 ++ galleries/examples/statistics/boxplot_vs_violin.py | 2 ++ galleries/examples/statistics/bxp.py | 2 ++ galleries/examples/statistics/confidence_ellipse.py | 8 ++++++++ galleries/examples/statistics/customized_violin.py | 2 ++ galleries/examples/statistics/errorbar.py | 3 +++ galleries/examples/statistics/errorbar_features.py | 2 ++ galleries/examples/statistics/errorbar_limits.py | 2 ++ galleries/examples/statistics/errorbars_and_boxes.py | 8 ++++++++ galleries/examples/statistics/hexbin_demo.py | 2 ++ galleries/examples/statistics/hist.py | 9 +++++++++ galleries/examples/statistics/histogram_bihistogram.py | 4 ++++ galleries/examples/statistics/histogram_cumulative.py | 2 ++ galleries/examples/statistics/histogram_histtypes.py | 2 ++ galleries/examples/statistics/histogram_multihist.py | 2 ++ galleries/examples/statistics/histogram_normalization.py | 2 ++ .../statistics/multiple_histograms_side_by_side.py | 7 +++++++ galleries/examples/statistics/time_series_histogram.py | 8 ++++++++ galleries/examples/statistics/violinplot.py | 2 ++ 21 files changed, 75 insertions(+) diff --git a/galleries/examples/statistics/boxplot.py b/galleries/examples/statistics/boxplot.py index ccdaab97d24a..6d30cbd4b5f0 100644 --- a/galleries/examples/statistics/boxplot.py +++ b/galleries/examples/statistics/boxplot.py @@ -97,6 +97,8 @@ # %% # +# .. tags:: plot-type: boxplot, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/boxplot_color.py b/galleries/examples/statistics/boxplot_color.py index 3491253aaf3e..acdb37d7d520 100644 --- a/galleries/examples/statistics/boxplot_color.py +++ b/galleries/examples/statistics/boxplot_color.py @@ -36,6 +36,8 @@ # %% # +# .. tags:: styling: color, domain: statistics, plot-type: boxplot +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/boxplot_demo.py b/galleries/examples/statistics/boxplot_demo.py index eca0e152078e..ec23408c0bfc 100644 --- a/galleries/examples/statistics/boxplot_demo.py +++ b/galleries/examples/statistics/boxplot_demo.py @@ -247,6 +247,8 @@ def fake_bootstrapper(n): # %% # +# .. tags:: domain: statistics, plot-type: boxplot +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/boxplot_vs_violin.py b/galleries/examples/statistics/boxplot_vs_violin.py index dce8912013b0..f277e737e65c 100644 --- a/galleries/examples/statistics/boxplot_vs_violin.py +++ b/galleries/examples/statistics/boxplot_vs_violin.py @@ -54,6 +54,8 @@ # %% # +# .. tags:: plot-type: violin, plot-type: boxplot, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/bxp.py b/galleries/examples/statistics/bxp.py index b12bfebd16cc..3ddd164df742 100644 --- a/galleries/examples/statistics/bxp.py +++ b/galleries/examples/statistics/bxp.py @@ -64,6 +64,8 @@ # %% # +# .. tags:: plot-type: speciality, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/confidence_ellipse.py b/galleries/examples/statistics/confidence_ellipse.py index 27b06146a44e..4ac0917f4bda 100644 --- a/galleries/examples/statistics/confidence_ellipse.py +++ b/galleries/examples/statistics/confidence_ellipse.py @@ -217,6 +217,14 @@ def get_correlated_dataset(n, dependency, mu, scale): # %% # +# .. tags:: +# +# plot-type: speciality +# plot-type: scatter +# component: ellipse +# component: patch +# domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/customized_violin.py b/galleries/examples/statistics/customized_violin.py index c1d2e432ca2e..29ddcda92fbe 100644 --- a/galleries/examples/statistics/customized_violin.py +++ b/galleries/examples/statistics/customized_violin.py @@ -73,6 +73,8 @@ def set_axis_style(ax, labels): # %% # +# .. tags:: plot-type: violin, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbar.py b/galleries/examples/statistics/errorbar.py index a25cadf88211..019590dc3f32 100644 --- a/galleries/examples/statistics/errorbar.py +++ b/galleries/examples/statistics/errorbar.py @@ -21,6 +21,9 @@ # %% # +# +# .. tags:: plot-type: errorbar, domain: statistics, +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbar_features.py b/galleries/examples/statistics/errorbar_features.py index 349cc89ff2e0..8abaffcda537 100644 --- a/galleries/examples/statistics/errorbar_features.py +++ b/galleries/examples/statistics/errorbar_features.py @@ -48,6 +48,8 @@ # %% # +# .. tags:: plot-type: errorbar, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbar_limits.py b/galleries/examples/statistics/errorbar_limits.py index d5b0e476d894..f1d26460d947 100644 --- a/galleries/examples/statistics/errorbar_limits.py +++ b/galleries/examples/statistics/errorbar_limits.py @@ -77,6 +77,8 @@ # %% # +# .. tags:: plot-type: errorbar, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/errorbars_and_boxes.py b/galleries/examples/statistics/errorbars_and_boxes.py index 54c8786096c7..b45eee751137 100644 --- a/galleries/examples/statistics/errorbars_and_boxes.py +++ b/galleries/examples/statistics/errorbars_and_boxes.py @@ -71,6 +71,14 @@ def make_error_boxes(ax, xdata, ydata, xerror, yerror, facecolor='r', # %% # +# +# .. tags:: +# +# plot-type: errorbar +# component: rectangle +# component: patchcollection +# domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/hexbin_demo.py b/galleries/examples/statistics/hexbin_demo.py index b9a6206a934f..bd1522772aae 100644 --- a/galleries/examples/statistics/hexbin_demo.py +++ b/galleries/examples/statistics/hexbin_demo.py @@ -35,6 +35,8 @@ # %% # +# .. tags:: plot-type: histogram, plot-type: hexbin, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/hist.py b/galleries/examples/statistics/hist.py index 8b06093913df..e31aca0228c2 100644 --- a/galleries/examples/statistics/hist.py +++ b/galleries/examples/statistics/hist.py @@ -103,6 +103,15 @@ # %% # +# .. tags:: +# +# plot-type: histogram, +# plot-type: histogram2d +# domain: statistics +# styling: color, +# component: normalization +# component: patch +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_bihistogram.py b/galleries/examples/statistics/histogram_bihistogram.py index 7bfae14e9285..73f549493438 100644 --- a/galleries/examples/statistics/histogram_bihistogram.py +++ b/galleries/examples/statistics/histogram_bihistogram.py @@ -43,3 +43,7 @@ ax.legend() plt.show() + +# %% +# +# .. tags:: plot-type: histogram, domain: statistics, purpose: showcase diff --git a/galleries/examples/statistics/histogram_cumulative.py b/galleries/examples/statistics/histogram_cumulative.py index 9ce16568d126..d87305629f8d 100644 --- a/galleries/examples/statistics/histogram_cumulative.py +++ b/galleries/examples/statistics/histogram_cumulative.py @@ -67,6 +67,8 @@ # %% # +# .. tags:: plot-type: ecdf, plot-type: histogram, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_histtypes.py b/galleries/examples/statistics/histogram_histtypes.py index 0188d7bf5d0f..53d6425cf4dc 100644 --- a/galleries/examples/statistics/histogram_histtypes.py +++ b/galleries/examples/statistics/histogram_histtypes.py @@ -51,6 +51,8 @@ # %% # +# .. tags:: plot-type: histogram, domain: statistics, purpose: reference +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_multihist.py b/galleries/examples/statistics/histogram_multihist.py index f1957dc38939..78ff03719057 100644 --- a/galleries/examples/statistics/histogram_multihist.py +++ b/galleries/examples/statistics/histogram_multihist.py @@ -47,6 +47,8 @@ # %% # +# .. tags:: plot-type: histogram, domain: statistics, purpose: reference +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/histogram_normalization.py b/galleries/examples/statistics/histogram_normalization.py index 9418b7af002b..2c423edad208 100644 --- a/galleries/examples/statistics/histogram_normalization.py +++ b/galleries/examples/statistics/histogram_normalization.py @@ -243,6 +243,8 @@ # %% # +# .. tags:: plot-type: histogram, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/multiple_histograms_side_by_side.py b/galleries/examples/statistics/multiple_histograms_side_by_side.py index 3c5766f8e546..733aed51f253 100644 --- a/galleries/examples/statistics/multiple_histograms_side_by_side.py +++ b/galleries/examples/statistics/multiple_histograms_side_by_side.py @@ -63,6 +63,13 @@ # %% # +# .. tags:: +# +# domain: statistics +# plot-type: barh +# plot-type: histogram +# styling: position +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/time_series_histogram.py b/galleries/examples/statistics/time_series_histogram.py index 371d182915b8..6f9a543fb4e5 100644 --- a/galleries/examples/statistics/time_series_histogram.py +++ b/galleries/examples/statistics/time_series_histogram.py @@ -94,6 +94,14 @@ # %% # +# .. tags:: +# +# plot-type: histogram2d +# plot-type: pcolormesh +# purpose: storytelling +# styling: color +# component: colormap +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown diff --git a/galleries/examples/statistics/violinplot.py b/galleries/examples/statistics/violinplot.py index afcc1c977034..3d0d44538032 100644 --- a/galleries/examples/statistics/violinplot.py +++ b/galleries/examples/statistics/violinplot.py @@ -106,6 +106,8 @@ # %% # +# .. tags:: plot-type: violin, domain: statistics +# # .. admonition:: References # # The use of the following functions, methods, classes and modules is shown From d6270b1ec462118f8181f98442a985d5e0a99a24 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 28 Oct 2024 23:05:33 -0400 Subject: [PATCH 37/49] Backport PR #29031: DOC: Fix copy-paste typo in ColorSequenceRegistry --- lib/matplotlib/colors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 5f40e7b0fb9a..2c0d1b5d9a4f 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -105,7 +105,7 @@ class ColorSequenceRegistry(Mapping): Read access uses a dict-like interface mapping names to lists of colors:: import matplotlib as mpl - cmap = mpl.color_sequences['tab10'] + colors = mpl.color_sequences['tab10'] The returned lists are copies, so that their modification does not change the global definition of the color sequence. From f9e680177baf36ffa237a49af5fa993b677d7b38 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:56:09 +0100 Subject: [PATCH 38/49] Backport PR #29036: Don't pass redundant inline=True to example clabel() calls. --- .../images_contours_and_fields/contour_demo.py | 12 ++++++------ .../images_contours_and_fields/contour_label_demo.py | 4 ++-- galleries/examples/misc/demo_agg_filter.py | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/galleries/examples/images_contours_and_fields/contour_demo.py b/galleries/examples/images_contours_and_fields/contour_demo.py index 1d64986850f5..885a8a3c2005 100644 --- a/galleries/examples/images_contours_and_fields/contour_demo.py +++ b/galleries/examples/images_contours_and_fields/contour_demo.py @@ -30,7 +30,7 @@ fig, ax = plt.subplots() CS = ax.contour(X, Y, Z) -ax.clabel(CS, inline=True, fontsize=10) +ax.clabel(CS, fontsize=10) ax.set_title('Simplest default with labels') # %% @@ -42,7 +42,7 @@ CS = ax.contour(X, Y, Z) manual_locations = [ (-1, -1.4), (-0.62, -0.7), (-2, 0.5), (1.7, 1.2), (2.0, 1.4), (2.4, 1.7)] -ax.clabel(CS, inline=True, fontsize=10, manual=manual_locations) +ax.clabel(CS, fontsize=10, manual=manual_locations) ax.set_title('labels at selected locations') # %% @@ -50,7 +50,7 @@ fig, ax = plt.subplots() CS = ax.contour(X, Y, Z, 6, colors='k') # Negative contours default to dashed. -ax.clabel(CS, fontsize=9, inline=True) +ax.clabel(CS, fontsize=9) ax.set_title('Single color - negative contours dashed') # %% @@ -59,7 +59,7 @@ plt.rcParams['contour.negative_linestyle'] = 'solid' fig, ax = plt.subplots() CS = ax.contour(X, Y, Z, 6, colors='k') # Negative contours default to dashed. -ax.clabel(CS, fontsize=9, inline=True) +ax.clabel(CS, fontsize=9) ax.set_title('Single color - negative contours solid') # %% @@ -70,7 +70,7 @@ linewidths=np.arange(.5, 4, .5), colors=('r', 'green', 'blue', (1, 1, 0), '#afeeee', '0.5'), ) -ax.clabel(CS, fontsize=9, inline=True) +ax.clabel(CS, fontsize=9) ax.set_title('Crazy lines') # %% @@ -90,7 +90,7 @@ CS.set_linewidth(lws) ax.clabel(CS, levels[1::2], # label every second level - inline=True, fmt='%1.1f', fontsize=14) + fmt='%1.1f', fontsize=14) # make a colorbar for the contour lines CB = fig.colorbar(CS, shrink=0.8) diff --git a/galleries/examples/images_contours_and_fields/contour_label_demo.py b/galleries/examples/images_contours_and_fields/contour_label_demo.py index 57f29c827757..0b24b57f6afd 100644 --- a/galleries/examples/images_contours_and_fields/contour_label_demo.py +++ b/galleries/examples/images_contours_and_fields/contour_label_demo.py @@ -43,7 +43,7 @@ def fmt(x): fig, ax = plt.subplots() CS = ax.contour(X, Y, Z) -ax.clabel(CS, CS.levels, inline=True, fmt=fmt, fontsize=10) +ax.clabel(CS, CS.levels, fmt=fmt, fontsize=10) # %% # Label contours with arbitrary strings using a dictionary @@ -59,7 +59,7 @@ def fmt(x): fmt[l] = s # Label every other level using strings -ax1.clabel(CS1, CS1.levels[::2], inline=True, fmt=fmt, fontsize=10) +ax1.clabel(CS1, CS1.levels[::2], fmt=fmt, fontsize=10) # %% # Use a Formatter diff --git a/galleries/examples/misc/demo_agg_filter.py b/galleries/examples/misc/demo_agg_filter.py index 5c2ad71a6673..302250ced9f0 100644 --- a/galleries/examples/misc/demo_agg_filter.py +++ b/galleries/examples/misc/demo_agg_filter.py @@ -188,7 +188,6 @@ def filtered_text(ax): # contour label cl = ax.clabel(CS, levels[1::2], # label every second level - inline=True, fmt='%1.1f', fontsize=11) From 9b1b45bf8bb30609f7155305000b4aebbc61ec39 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:56:09 +0100 Subject: [PATCH 39/49] Backport PR #29036: Don't pass redundant inline=True to example clabel() calls. --- .../images_contours_and_fields/contour_demo.py | 12 ++++++------ .../images_contours_and_fields/contour_label_demo.py | 4 ++-- galleries/examples/misc/demo_agg_filter.py | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/galleries/examples/images_contours_and_fields/contour_demo.py b/galleries/examples/images_contours_and_fields/contour_demo.py index 1d64986850f5..885a8a3c2005 100644 --- a/galleries/examples/images_contours_and_fields/contour_demo.py +++ b/galleries/examples/images_contours_and_fields/contour_demo.py @@ -30,7 +30,7 @@ fig, ax = plt.subplots() CS = ax.contour(X, Y, Z) -ax.clabel(CS, inline=True, fontsize=10) +ax.clabel(CS, fontsize=10) ax.set_title('Simplest default with labels') # %% @@ -42,7 +42,7 @@ CS = ax.contour(X, Y, Z) manual_locations = [ (-1, -1.4), (-0.62, -0.7), (-2, 0.5), (1.7, 1.2), (2.0, 1.4), (2.4, 1.7)] -ax.clabel(CS, inline=True, fontsize=10, manual=manual_locations) +ax.clabel(CS, fontsize=10, manual=manual_locations) ax.set_title('labels at selected locations') # %% @@ -50,7 +50,7 @@ fig, ax = plt.subplots() CS = ax.contour(X, Y, Z, 6, colors='k') # Negative contours default to dashed. -ax.clabel(CS, fontsize=9, inline=True) +ax.clabel(CS, fontsize=9) ax.set_title('Single color - negative contours dashed') # %% @@ -59,7 +59,7 @@ plt.rcParams['contour.negative_linestyle'] = 'solid' fig, ax = plt.subplots() CS = ax.contour(X, Y, Z, 6, colors='k') # Negative contours default to dashed. -ax.clabel(CS, fontsize=9, inline=True) +ax.clabel(CS, fontsize=9) ax.set_title('Single color - negative contours solid') # %% @@ -70,7 +70,7 @@ linewidths=np.arange(.5, 4, .5), colors=('r', 'green', 'blue', (1, 1, 0), '#afeeee', '0.5'), ) -ax.clabel(CS, fontsize=9, inline=True) +ax.clabel(CS, fontsize=9) ax.set_title('Crazy lines') # %% @@ -90,7 +90,7 @@ CS.set_linewidth(lws) ax.clabel(CS, levels[1::2], # label every second level - inline=True, fmt='%1.1f', fontsize=14) + fmt='%1.1f', fontsize=14) # make a colorbar for the contour lines CB = fig.colorbar(CS, shrink=0.8) diff --git a/galleries/examples/images_contours_and_fields/contour_label_demo.py b/galleries/examples/images_contours_and_fields/contour_label_demo.py index 57f29c827757..0b24b57f6afd 100644 --- a/galleries/examples/images_contours_and_fields/contour_label_demo.py +++ b/galleries/examples/images_contours_and_fields/contour_label_demo.py @@ -43,7 +43,7 @@ def fmt(x): fig, ax = plt.subplots() CS = ax.contour(X, Y, Z) -ax.clabel(CS, CS.levels, inline=True, fmt=fmt, fontsize=10) +ax.clabel(CS, CS.levels, fmt=fmt, fontsize=10) # %% # Label contours with arbitrary strings using a dictionary @@ -59,7 +59,7 @@ def fmt(x): fmt[l] = s # Label every other level using strings -ax1.clabel(CS1, CS1.levels[::2], inline=True, fmt=fmt, fontsize=10) +ax1.clabel(CS1, CS1.levels[::2], fmt=fmt, fontsize=10) # %% # Use a Formatter diff --git a/galleries/examples/misc/demo_agg_filter.py b/galleries/examples/misc/demo_agg_filter.py index 5c2ad71a6673..302250ced9f0 100644 --- a/galleries/examples/misc/demo_agg_filter.py +++ b/galleries/examples/misc/demo_agg_filter.py @@ -188,7 +188,6 @@ def filtered_text(ax): # contour label cl = ax.clabel(CS, levels[1::2], # label every second level - inline=True, fmt='%1.1f', fontsize=11) From befcf72e1610f28e634c9b2d6479294992d0d918 Mon Sep 17 00:00:00 2001 From: Greg Lucas Date: Tue, 29 Oct 2024 14:56:23 -0600 Subject: [PATCH 40/49] Backport PR #29035: FIX: Don't set_wmclass on GTK3 --- lib/matplotlib/backends/_backend_gtk.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/matplotlib/backends/_backend_gtk.py b/lib/matplotlib/backends/_backend_gtk.py index 565d92932023..ac443730e28a 100644 --- a/lib/matplotlib/backends/_backend_gtk.py +++ b/lib/matplotlib/backends/_backend_gtk.py @@ -143,7 +143,6 @@ def __init__(self, canvas, num): super().__init__(canvas, num) if gtk_ver == 3: - self.window.set_wmclass("matplotlib", "Matplotlib") icon_ext = "png" if sys.platform == "win32" else "svg" self.window.set_icon_from_file( str(cbook._get_data_path(f"images/matplotlib.{icon_ext}"))) From 985e8f4f92c35518fd452e95c127425411e36fd8 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 30 Oct 2024 16:05:32 -0400 Subject: [PATCH 41/49] Backport PR #28981: FIX: macos: Use standard NSApp run loop in our input hook --- src/_macosx.m | 110 +++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/src/_macosx.m b/src/_macosx.m index fda928536ab5..1f291b52f6ba 100755 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -40,60 +40,84 @@ static bool keyChangeCapsLock = false; /* Keep track of the current mouse up/down state for open/closed cursor hand */ static bool leftMouseGrabbing = false; -/* Keep track of whether stdin has been received */ -static bool stdin_received = false; -static bool stdin_sigint = false; // Global variable to store the original SIGINT handler static PyOS_sighandler_t originalSigintAction = NULL; -// Signal handler for SIGINT, only sets a flag to exit the run loop +// Stop the current app's run loop, sending an event to ensure it actually stops +static void stopWithEvent() { + [NSApp stop: nil]; + // Post an event to trigger the actual stopping. + [NSApp postEvent: [NSEvent otherEventWithType: NSEventTypeApplicationDefined + location: NSZeroPoint + modifierFlags: 0 + timestamp: 0 + windowNumber: 0 + context: nil + subtype: 0 + data1: 0 + data2: 0] + atStart: YES]; +} + +// Signal handler for SIGINT, only argument matching for stopWithEvent static void handleSigint(int signal) { - stdin_sigint = true; + stopWithEvent(); +} + +// Helper function to flush all events. +// This is needed in some instances to ensure e.g. that windows are properly closed. +// It is used in the input hook as well as wrapped in a version callable from Python. +static void flushEvents() { + while (true) { + NSEvent* event = [NSApp nextEventMatchingMask: NSEventMaskAny + untilDate: [NSDate distantPast] + inMode: NSDefaultRunLoopMode + dequeue: YES]; + if (!event) { + break; + } + [NSApp sendEvent:event]; + } } static int wait_for_stdin() { - @autoreleasepool { - stdin_received = false; - stdin_sigint = false; + // Short circuit if no windows are active + // Rely on Python's input handling to manage CPU usage + // This queries the NSApp, rather than using our FigureWindowCount because that is decremented when events still + // need to be processed to properly close the windows. + if (![[NSApp windows] count]) { + flushEvents(); + return 1; + } + @autoreleasepool { // Set up a SIGINT handler to interrupt the event loop if ctrl+c comes in too originalSigintAction = PyOS_setsig(SIGINT, handleSigint); // Create an NSFileHandle for standard input NSFileHandle *stdinHandle = [NSFileHandle fileHandleWithStandardInput]; + // Register for data available notifications on standard input - [[NSNotificationCenter defaultCenter] addObserverForName: NSFileHandleDataAvailableNotification - object: stdinHandle - queue: [NSOperationQueue mainQueue] // Use the main queue - usingBlock: ^(NSNotification *notification) { - // Mark that input has been received - stdin_received = true; - } + id notificationID = [[NSNotificationCenter defaultCenter] addObserverForName: NSFileHandleDataAvailableNotification + object: stdinHandle + queue: [NSOperationQueue mainQueue] // Use the main queue + usingBlock: ^(NSNotification *notification) {stopWithEvent();} ]; // Wait in the background for anything that happens to stdin [stdinHandle waitForDataInBackgroundAndNotify]; - // continuously run an event loop until the stdin_received flag is set to exit - while (!stdin_received && !stdin_sigint) { - // This loop is similar to the main event loop and flush_events which have - // Py_[BEGIN|END]_ALLOW_THREADS surrounding the loop. - // This should not be necessary here because PyOS_InputHook releases the GIL for us. - while (true) { - NSEvent *event = [NSApp nextEventMatchingMask: NSEventMaskAny - untilDate: [NSDate distantPast] - inMode: NSDefaultRunLoopMode - dequeue: YES]; - if (!event) { break; } - [NSApp sendEvent: event]; - } - } + // Run the application's event loop, which will be interrupted on stdin or SIGINT + [NSApp run]; + // Remove the input handler as an observer - [[NSNotificationCenter defaultCenter] removeObserver: stdinHandle]; + [[NSNotificationCenter defaultCenter] removeObserver: notificationID]; + // Restore the original SIGINT handler upon exiting the function PyOS_setsig(SIGINT, originalSigintAction); + return 1; } } @@ -236,18 +260,7 @@ static void lazy_init(void) { static PyObject* stop(PyObject* self) { - [NSApp stop: nil]; - // Post an event to trigger the actual stopping. - [NSApp postEvent: [NSEvent otherEventWithType: NSEventTypeApplicationDefined - location: NSZeroPoint - modifierFlags: 0 - timestamp: 0 - windowNumber: 0 - context: nil - subtype: 0 - data1: 0 - data2: 0] - atStart: YES]; + stopWithEvent(); Py_RETURN_NONE; } @@ -382,20 +395,9 @@ static CGFloat _get_device_scale(CGContextRef cr) // We run the app, matching any events that are waiting in the queue // to process, breaking out of the loop when no events remain and // displaying the canvas if needed. - NSEvent *event; - Py_BEGIN_ALLOW_THREADS - while (true) { - event = [NSApp nextEventMatchingMask: NSEventMaskAny - untilDate: [NSDate distantPast] - inMode: NSDefaultRunLoopMode - dequeue: YES]; - if (!event) { - break; - } - [NSApp sendEvent:event]; - } + flushEvents(); Py_END_ALLOW_THREADS From c87f8078114310ac93c548686764ef5e5aaa8861 Mon Sep 17 00:00:00 2001 From: Ruth Comer <10599679+rcomer@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:02:56 +0000 Subject: [PATCH 42/49] Backport PR #29120: DOC: Switch nested pie example from cmaps to color_sequences --- galleries/examples/pie_and_polar_charts/nested_pie.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/galleries/examples/pie_and_polar_charts/nested_pie.py b/galleries/examples/pie_and_polar_charts/nested_pie.py index c83b4f6f84ee..61cb5e6ee429 100644 --- a/galleries/examples/pie_and_polar_charts/nested_pie.py +++ b/galleries/examples/pie_and_polar_charts/nested_pie.py @@ -31,9 +31,9 @@ size = 0.3 vals = np.array([[60., 32.], [37., 40.], [29., 10.]]) -cmap = plt.colormaps["tab20c"] -outer_colors = cmap(np.arange(3)*4) -inner_colors = cmap([1, 2, 5, 6, 9, 10]) +tab20c = plt.color_sequences["tab20c"] +outer_colors = [tab20c[i] for i in [0, 4, 8]] +inner_colors = [tab20c[i] for i in [1, 2, 5, 6, 9, 10]] ax.pie(vals.sum(axis=1), radius=1, colors=outer_colors, wedgeprops=dict(width=size, edgecolor='w')) From 8d8d1d6a7ad9ff03d86ec2d30c65002eb5a93ba4 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 20 Nov 2024 14:46:04 -0500 Subject: [PATCH 43/49] Backport CI config updates to v3.9.x (#29149) This includes updates to `actions/attest-build-provenance`, `pypa/cibuildwheel`, `pypa/gh-action-pypi-publish`, `deadsnakes/action`, and cleanup of `workflow_dispatch` and outdated skips. --- .github/workflows/cibuildwheel.yml | 18 ++++++++---------- .github/workflows/cygwin.yml | 1 - .github/workflows/tests.yml | 3 +-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/.github/workflows/cibuildwheel.yml b/.github/workflows/cibuildwheel.yml index a145b5bbcc08..aa0366ad16ff 100644 --- a/.github/workflows/cibuildwheel.yml +++ b/.github/workflows/cibuildwheel.yml @@ -143,13 +143,11 @@ jobs: path: dist/ - name: Build wheels for CPython 3.13 - uses: pypa/cibuildwheel@bd033a44476646b606efccdd5eed92d5ea1d77ad # v2.20.0 + uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: CIBW_BUILD: "cp313-* cp313t-*" - # No free-threading wheels for NumPy; musllinux skipped for main builds also. - CIBW_SKIP: "cp313t-win_amd64 *-musllinux_aarch64" CIBW_BUILD_FRONTEND: "pip; args: --pre --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" CIBW_FREE_THREADED_SUPPORT: true @@ -163,7 +161,7 @@ jobs: CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for CPython 3.12 - uses: pypa/cibuildwheel@bd033a44476646b606efccdd5eed92d5ea1d77ad # v2.20.0 + uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: @@ -171,7 +169,7 @@ jobs: CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for CPython 3.11 - uses: pypa/cibuildwheel@bd033a44476646b606efccdd5eed92d5ea1d77ad # v2.20.0 + uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: @@ -179,7 +177,7 @@ jobs: CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for CPython 3.10 - uses: pypa/cibuildwheel@bd033a44476646b606efccdd5eed92d5ea1d77ad # v2.20.0 + uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: @@ -187,7 +185,7 @@ jobs: CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for CPython 3.9 - uses: pypa/cibuildwheel@7e5a838a63ac8128d71ab2dfd99e4634dd1bca09 # v2.19.2 + uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: @@ -195,7 +193,7 @@ jobs: CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for PyPy - uses: pypa/cibuildwheel@bd033a44476646b606efccdd5eed92d5ea1d77ad # v2.20.0 + uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: @@ -231,9 +229,9 @@ jobs: run: ls dist - name: Generate artifact attestation for sdist and wheel - uses: actions/attest-build-provenance@210c1913531870065f03ce1f9440dd87bc0938cd # v1.4.0 + uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4 with: subject-path: dist/matplotlib-* - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0 # v1.9.0 + uses: pypa/gh-action-pypi-publish@15c56dba361d8335944d31a2ecd17d700fc7bcbc # v1.12.2 diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index 58c132315b6f..a3f93ba195a8 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -29,7 +29,6 @@ on: # 5:47 UTC on Saturdays - cron: "47 5 * * 6" workflow_dispatch: - workflow: "*" permissions: contents: read diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4100fda43a36..853311366ee3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,6 @@ on: # 5:47 UTC on Saturdays - cron: "47 5 * * 6" workflow_dispatch: - workflow: "*" env: NO_AT_BRIDGE: 1 # Necessary for GTK3 interactive test. @@ -127,7 +126,7 @@ jobs: allow-prereleases: true - name: Set up Python ${{ matrix.python-version }} - uses: deadsnakes/action@6c8b9b82fe0b4344f4b98f2775fcc395df45e494 # v3.1.0 + uses: deadsnakes/action@e640ac8743173a67cca4d7d77cd837e514bf98e8 # v3.2.0 if: matrix.python-version == '3.13t' with: python-version: '3.13' From d71ff494bbf808f029cd6a3f3c0de061ea480010 Mon Sep 17 00:00:00 2001 From: "Lumberbot (aka Jack)" <39504233+meeseeksmachine@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:54:15 -0800 Subject: [PATCH 44/49] Backport PR #29153: Bump codecov/codecov-action from 4 to 5 in the actions group (#29165) Co-authored-by: Greg Lucas --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 853311366ee3..6d2fe41546f1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -388,7 +388,7 @@ jobs: fi - name: Upload code coverage if: ${{ !cancelled() && github.event_name != 'schedule' }} - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: name: "${{ matrix.python-version }} ${{ matrix.os }} ${{ matrix.name-suffix }}" token: ${{ secrets.CODECOV_TOKEN }} From c4bfd54a058f9124bfb75beccafdfd03432b3778 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 22 Nov 2024 21:50:55 -0500 Subject: [PATCH 45/49] Backport PR #29148: Don't fail on equal-but-differently-named cmaps in qt figureoptions. --- lib/matplotlib/backends/qt_editor/figureoptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/qt_editor/figureoptions.py b/lib/matplotlib/backends/qt_editor/figureoptions.py index c36bbeb62641..3c2eaf1bacd3 100644 --- a/lib/matplotlib/backends/qt_editor/figureoptions.py +++ b/lib/matplotlib/backends/qt_editor/figureoptions.py @@ -149,7 +149,7 @@ def prepare_data(d, init): cmaps = [(cmap, name) for name, cmap in sorted(cm._colormaps.items())] for label, mappable in labeled_mappables: cmap = mappable.get_cmap() - if cmap not in cm._colormaps.values(): + if cmap.name not in cm._colormaps: cmaps = [(cmap, cmap.name), *cmaps] low, high = mappable.get_clim() mappabledata = [ From dd5777232d288970697f4effafd38946d541784c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 20 Nov 2024 23:48:23 -0500 Subject: [PATCH 46/49] Backport PR #29163: ci: Remove outdated pkg-config package on macOS --- .github/workflows/tests.yml | 2 ++ azure-pipelines.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6d2fe41546f1..6f604db8cd0b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -202,6 +202,8 @@ jobs: brew unlink ${python_package} brew link --overwrite ${python_package} done + # Workaround for https://github.com/actions/runner-images/issues/10984 + brew uninstall --ignore-dependencies --force pkg-config@0.29.2 brew install ccache ghostscript gobject-introspection gtk4 ninja brew install --cask font-noto-sans-cjk inkscape ;; diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e2829ce81e9f..00edc8e9a412 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -131,6 +131,8 @@ stages: brew unlink ${python_package} brew link --overwrite ${python_package} done + # Workaround for https://github.com/actions/runner-images/issues/10984 + brew uninstall --ignore-dependencies --force pkg-config@0.29.2 brew install --cask xquartz brew install ccache ffmpeg imagemagick mplayer ninja pkg-config brew install --cask font-noto-sans-cjk-sc From 562d45862d411925f98b489270ea7a206a9a3bb1 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Tue, 26 Nov 2024 10:14:08 -0500 Subject: [PATCH 47/49] Backport PR #29191: ci: Simplify 3.13t test setup --- .github/workflows/tests.yml | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6f604db8cd0b..dc216c6959f0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -126,11 +126,11 @@ jobs: allow-prereleases: true - name: Set up Python ${{ matrix.python-version }} - uses: deadsnakes/action@e640ac8743173a67cca4d7d77cd837e514bf98e8 # v3.2.0 + uses: Quansight-Labs/setup-python@b9ab292c751a42bcd2bb465b7fa202ea2c3f5796 # v5.3.1 if: matrix.python-version == '3.13t' with: - python-version: '3.13' - nogil: true + python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Install OS dependencies run: | @@ -177,11 +177,6 @@ jobs: texlive-luatex \ texlive-pictures \ texlive-xetex - if [[ "${{ matrix.python-version }}" = '3.13t' ]]; then - # TODO: Remove this once setup-python supports nogil distributions. - sudo apt-get install -yy --no-install-recommends \ - python3.13-tk-nogil - fi if [[ "${{ matrix.os }}" = ubuntu-20.04 ]]; then sudo apt-get install -yy --no-install-recommends libopengl0 else # ubuntu-22.04 @@ -245,15 +240,6 @@ jobs: 4-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}- 4-${{ runner.os }}-py${{ matrix.python-version }}-mpl- - - name: Install the nightly dependencies - if: matrix.python-version == '3.13t' - run: | - python -m pip install pytz tzdata python-dateutil # Must be installed for Pandas. - python -m pip install \ - --pre \ - --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \ - --upgrade --only-binary=:all: numpy pandas pillow contourpy - - name: Install Python dependencies run: | # Upgrade pip and setuptools and wheel to get as clean an install as From 4ca8d68b6b161b41492fb27c2431c3adc4d26051 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 30 Nov 2024 03:28:23 -0500 Subject: [PATCH 48/49] DOC: Create release notes for 3.9.3 --- doc/users/github_stats.rst | 156 ++++++++++-------- .../prev_whats_new/github_stats_3.9.2.rst | 96 +++++++++++ doc/users/release_notes.rst | 1 + 3 files changed, 181 insertions(+), 72 deletions(-) create mode 100644 doc/users/prev_whats_new/github_stats_3.9.2.rst diff --git a/doc/users/github_stats.rst b/doc/users/github_stats.rst index d357a6759d30..bec073081a68 100644 --- a/doc/users/github_stats.rst +++ b/doc/users/github_stats.rst @@ -1,99 +1,111 @@ .. _github-stats: -GitHub statistics for 3.9.2 (Aug 12, 2024) +GitHub statistics for 3.9.3 (Nov 30, 2024) ========================================== -GitHub statistics for 2024/07/04 (tag: v3.9.1) - 2024/08/12 +GitHub statistics for 2024/08/12 (tag: v3.9.2) - 2024/11/30 These lists are automatically generated, and may be incomplete or contain duplicates. -We closed 9 issues and merged 45 pull requests. -The full list can be seen `on GitHub `__ +We closed 6 issues and merged 62 pull requests. +The full list can be seen `on GitHub `__ -The following 20 authors contributed 67 commits. +The following 18 authors contributed 90 commits. -* Adam J. Stewart -* Anthony Lee -* Caitlin Hathaway -* ClarkeAC +* Andresporcruz +* Antony Lee +* Charlie LeWarne * dependabot[bot] * Elliott Sales de Andrade -* Filippo Balzaretti +* Gavin S * Greg Lucas * hannah -* Ian Thomas -* Jody Klymak * Kyle Sunden +* Kyra Cho +* kyracho +* Lumberbot (aka Jack) +* Michael Hinton * Oscar Gustafsson -* Randolf Scholz -* Refael Ackermann * Ruth Comer -* Scott Shambaugh -* Sean Smith * Thomas A Caswell * Tim Hoffmann +* vittoboa GitHub issues and pull requests: -Pull Requests (45): +Pull Requests (62): -* :ghpull:`28687`: BLD: Include MSVCP140 runtime statically -* :ghpull:`28679`: Run delvewheel with path to required msvcp140.dll -* :ghpull:`28695`: Backport PR #27797 on branch v3.9.x (DOC: Use video files for saving animations) -* :ghpull:`28688`: Backport PR #28293 and #28668: Enable 3.13 wheels and bump cibuildwheel -* :ghpull:`27797`: DOC: Use video files for saving animations -* :ghpull:`28692`: Backport PR #28632 on branch v3.9.x (DOC: Tell sphinx-gallery to link mpl_toolkits from our build) -* :ghpull:`28632`: DOC: Tell sphinx-gallery to link mpl_toolkits from our build -* :ghpull:`28668`: Bump the actions group with 2 updates -* :ghpull:`28686`: Backport PR #28682 on branch v3.9.x (Fix warnings from mingw compilers) -* :ghpull:`28682`: Fix warnings from mingw compilers -* :ghpull:`28676`: Backport PR #28577 on branch v3.9.x (Copy all internals from initial Tick to lazy ones) -* :ghpull:`28577`: Copy all internals from initial Tick to lazy ones -* :ghpull:`28674`: Backport PR #28650 on branch v3.9.x (remove out of date todos on animation.py) -* :ghpull:`28650`: remove out of date todos on animation.py -* :ghpull:`28656`: Backport PR #28649 on branch v3.9.x (FIX: improve formatting of image values in cases of singular norms) -* :ghpull:`28665`: Backport PR #28546 on branch v3.9.x (DOC: Clarify/simplify example of multiple images with one colorbar) -* :ghpull:`28649`: FIX: improve formatting of image values in cases of singular norms -* :ghpull:`28635`: BLD: windows wheels -* :ghpull:`28645`: Backport PR #28644 on branch v3.9.x (DOC: Fix matching for version switcher) -* :ghpull:`28640`: Backport PR #28634 on branch v3.9.x (Closed open div tag in color.ColorMap._repr_html_) -* :ghpull:`28634`: Closed open div tag in color.ColorMap._repr_html_ -* :ghpull:`28636`: Backport PR #28625 on branch v3.9.x (added typing_extensions.Self to _AxesBase.twinx) -* :ghpull:`28625`: added typing_extensions.Self to _AxesBase.twinx -* :ghpull:`28622`: Backport PR #28621 on branch v3.9.x (TYP: Fix a typo in animation.pyi) -* :ghpull:`28621`: TYP: Fix a typo in animation.pyi -* :ghpull:`28605`: Backport PR #28604 on branch v3.9.x (cycler signature update.) -* :ghpull:`28604`: cycler signature update. -* :ghpull:`28598`: Pin PyQt6 back on Ubuntu 20.04 -* :ghpull:`28596`: Backport PR #28518 on branch v3.9.x ([TYP] Fix overload of ``pyplot.subplots``) -* :ghpull:`28518`: [TYP] Fix overload of ``pyplot.subplots`` -* :ghpull:`28591`: Backport PR #28580 on branch v3.9.x (Bump actions/attest-build-provenance from 1.3.2 to 1.3.3 in the actions group) -* :ghpull:`28580`: Bump actions/attest-build-provenance from 1.3.2 to 1.3.3 in the actions group -* :ghpull:`28586`: Backport PR #28582 on branch v3.9.x (FIX: make sticky edge tolerance relative to data range) -* :ghpull:`28582`: FIX: make sticky edge tolerance relative to data range -* :ghpull:`28572`: Backport PR #28571 on branch v3.9.x (DOC: Add version directive to hatch parameter in stackplot) -* :ghpull:`28571`: DOC: Add version directive to hatch parameter in stackplot -* :ghpull:`28564`: Backport PR #28534 on branch v3.9.x ([BLD] Fix WSL build warning) -* :ghpull:`28563`: Backport PR #28526 on branch v3.9.x (Bump pypa/cibuildwheel from 2.19.1 to 2.19.2 in the actions group) -* :ghpull:`28534`: [BLD] Fix WSL build warning -* :ghpull:`28526`: Bump pypa/cibuildwheel from 2.19.1 to 2.19.2 in the actions group -* :ghpull:`28552`: Backport PR #28541 on branch v3.9.x (MNT: be more careful about disk I/O failures when writing font cache) -* :ghpull:`28541`: MNT: be more careful about disk I/O failures when writing font cache -* :ghpull:`28524`: Backport PR #28523 on branch v3.9.x (Fix value error when set widget size to zero while using FigureCanvasQT ) -* :ghpull:`28523`: Fix value error when set widget size to zero while using FigureCanvasQT -* :ghpull:`28519`: Backport PR #28517 on branch v3.9.x (DOC: better cross referencing for animations) +* :ghpull:`29195`: Backport PR #29191 on branch v3.9.x (ci: Simplify 3.13t test setup) +* :ghpull:`29191`: ci: Simplify 3.13t test setup +* :ghpull:`29176`: Backport PR #29148 on branch v3.9.x (Don't fail on equal-but-differently-named cmaps in qt figureoptions.) +* :ghpull:`29148`: Don't fail on equal-but-differently-named cmaps in qt figureoptions. +* :ghpull:`29165`: Backport PR #29153 on branch v3.9.x (Bump codecov/codecov-action from 4 to 5 in the actions group) +* :ghpull:`29153`: Bump codecov/codecov-action from 4 to 5 in the actions group +* :ghpull:`29149`: Backport CI config updates to v3.9.x +* :ghpull:`29121`: Backport PR #29120 on branch v3.9.x (DOC: Switch nested pie example from cmaps to color_sequences) +* :ghpull:`29071`: Bump pypa/gh-action-pypi-publish from 1.10.3 to 1.11.0 in the actions group +* :ghpull:`29046`: Backport PR #28981 on branch v3.9.x (FIX: macos: Use standard NSApp run loop in our input hook) +* :ghpull:`28981`: FIX: macos: Use standard NSApp run loop in our input hook +* :ghpull:`29041`: Backport PR #29035 on branch v3.9.x (FIX: Don't set_wmclass on GTK3) +* :ghpull:`29035`: FIX: Don't set_wmclass on GTK3 +* :ghpull:`29037`: Backport PR #29036 on branch v3.9.x (Don't pass redundant inline=True to example clabel() calls.) +* :ghpull:`29032`: Backport PR #27569 on branch v3.9.x (DOC: initial tags for statistics section of gallery) +* :ghpull:`29034`: Backport PR #29031 on branch v3.9.x (DOC: Fix copy-paste typo in ColorSequenceRegistry) +* :ghpull:`29031`: DOC: Fix copy-paste typo in ColorSequenceRegistry +* :ghpull:`29015`: Backport PR #29014 on branch v3.9.x (FIX: fake out setuptools scm in tox on ci) +* :ghpull:`29014`: FIX: fake out setuptools scm in tox on ci +* :ghpull:`29010`: Backport PR #29005 on branch v3.9.x (DOC: Update meson-python intersphinx link) +* :ghpull:`29006`: Backport PR #28993 on branch v3.9.x (FIX: contourf hatches use multiple edgecolors) +* :ghpull:`28993`: FIX: contourf hatches use multiple edgecolors +* :ghpull:`28988`: Backport PR #28987 on branch v3.9.x (Fix: Do not use numeric tolerances for axline special cases) +* :ghpull:`28947`: Backport PR #28925 on branch v3.9.x (TST: handle change in pytest.importorskip behavior) +* :ghpull:`28989`: Backport PR #28972 on branch v3.9.x (Switch macOS 12 runner images to macOS 13) +* :ghpull:`28972`: Switch macOS 12 runner images to macOS 13 +* :ghpull:`28987`: Fix: Do not use numeric tolerances for axline special cases +* :ghpull:`28954`: Backport PR #28952 on branch v3.9.x (BLD: update trove metadata to support py3.13) +* :ghpull:`28952`: BLD: update trove metadata to support py3.13 +* :ghpull:`28887`: Backport PR #28883 on branch v3.9.x (Only check X11 when running Tkinter tests) +* :ghpull:`28926`: Backport PR #28689 on branch v3.9.x (ci: Enable testing on Python 3.13) +* :ghpull:`28925`: TST: handle change in pytest.importorskip behavior +* :ghpull:`28945`: Backport PR #28943 on branch v3.9.x (DOC: Clarify the returned line of axhline()/axvline()) +* :ghpull:`28939`: Backport PR #28900 on branch v3.9.x (DOC: Improve fancybox demo) +* :ghpull:`28900`: DOC: Improve fancybox demo +* :ghpull:`28902`: Backport PR #28881 on branch v3.9.x (Fix ``axline`` for slopes <= 1E-8. Closes #28386) +* :ghpull:`28431`: Fix ``axline`` for slopes < 1E-8 +* :ghpull:`28881`: Fix ``axline`` for slopes <= 1E-8. Closes #28386 +* :ghpull:`28883`: Only check X11 when running Tkinter tests +* :ghpull:`28859`: Backport PR #28858 on branch v3.9.x (Fix flaky labelcolor tests) +* :ghpull:`28858`: Fix flaky labelcolor tests +* :ghpull:`28839`: Backport PR #28836 on branch v3.9.x (MNT: Use __init__ parameters of font properties) +* :ghpull:`28836`: MNT: Use __init__ parameters of font properties +* :ghpull:`28828`: Backport PR #28818 on branch v3.9.x (Resolve configdir so that it's not a symlink when is_dir() is called) +* :ghpull:`28818`: Resolve configdir so that it's not a symlink when is_dir() is called +* :ghpull:`28811`: Backport PR #28810 on branch v3.9.x (Document how to obtain sans-serif usetex math.) +* :ghpull:`28806`: Backport PR #28805 on branch v3.9.x (add brackets to satisfy the new sequence requirement) +* :ghpull:`28802`: Backport PR #28798 on branch v3.9.x (DOC: Correctly list modules that have been internalized) +* :ghpull:`28791`: Backport PR #28790 on branch v3.9.x (DOC: Fix duplicate Figure.set_dpi entry) +* :ghpull:`28787`: Backport PR #28706 on branch v3.9.x (Add Returns info to to_jshtml docstring) +* :ghpull:`28706`: Add Returns info to to_jshtml docstring +* :ghpull:`28751`: Backport PR #28271 on branch v3.9.x (Fix draggable legend disappearing when picking while use_blit=True) +* :ghpull:`28271`: Fix draggable legend disappearing when picking while use_blit=True +* :ghpull:`28747`: Backport PR #28743 on branch v3.9.x (Minor fixes in ticker docs) +* :ghpull:`28743`: Minor fixes in ticker docs +* :ghpull:`28738`: Backport PR #28737 on branch v3.9.x (TST: Fix image comparison directory for test_striped_lines) +* :ghpull:`28740`: Backport PR #28739 on branch v3.9.x (Tweak interactivity docs wording (and fix capitalization).) +* :ghpull:`28737`: TST: Fix image comparison directory for test_striped_lines +* :ghpull:`28733`: Backport PR #28732 on branch v3.9.x (Renames the minumumSizeHint method to minimumSizeHint) +* :ghpull:`28732`: Renames the minumumSizeHint method to minimumSizeHint +* :ghpull:`28689`: ci: Enable testing on Python 3.13 +* :ghpull:`28724`: Backport fixes from #28711 -Issues (9): +Issues (6): -* :ghissue:`28551`: [Bug]: Possible issue with Matplotlib 3.9.1 wheel on Windows only -* :ghissue:`28250`: [Doc]: Sphinx gallery links mispointed for Axes3D methods -* :ghissue:`28574`: [Bug]: Nondeterministic behavior with subplot spacing and constrained layout -* :ghissue:`28626`: [Doc]: Remove old TODO's from animation.py -* :ghissue:`28648`: [Bug]: format_image_data on an image of only zeros produces a large number of zeros -* :ghissue:`28624`: [Bug]: Bad type hint in ``_AxesBase.twinx()`` -* :ghissue:`28567`: [Bug]: sticky edge related changes for datetime plots -* :ghissue:`28533`: [Doc]: Stackplot hatch functionality has version dependencies -* :ghissue:`28538`: [Bug]: Permission denied when importing matplotlib.pyplot +* :ghissue:`28960`: [Bug]: High CPU utilization of the macosx backend +* :ghissue:`28990`: [Bug]: no longer able to set multiple hatch colors +* :ghissue:`28870`: [Bug]: axline doesn't work with some axes scales +* :ghissue:`28386`: [Bug]: Minor issue - Drawing an axline sets slopes less than 1E-8 to 0 +* :ghissue:`28817`: [Bug]: ``~/.config/matplotlib`` is never used because ``~/.config`` is a symlink +* :ghissue:`28716`: Size hint method in Qt backend should be named ``minimumSizeHint``, not ``minumumSizeHint`` Previous GitHub statistics diff --git a/doc/users/prev_whats_new/github_stats_3.9.2.rst b/doc/users/prev_whats_new/github_stats_3.9.2.rst new file mode 100644 index 000000000000..542e0d81ce32 --- /dev/null +++ b/doc/users/prev_whats_new/github_stats_3.9.2.rst @@ -0,0 +1,96 @@ +.. _github-stats-3-9-2: + +GitHub statistics for 3.9.2 (Aug 12, 2024) +========================================== + +GitHub statistics for 2024/07/04 (tag: v3.9.1) - 2024/08/12 + +These lists are automatically generated, and may be incomplete or contain duplicates. + +We closed 9 issues and merged 45 pull requests. +The full list can be seen `on GitHub `__ + +The following 20 authors contributed 67 commits. + +* Adam J. Stewart +* Anthony Lee +* Caitlin Hathaway +* ClarkeAC +* dependabot[bot] +* Elliott Sales de Andrade +* Filippo Balzaretti +* Greg Lucas +* hannah +* Ian Thomas +* Jody Klymak +* Kyle Sunden +* Oscar Gustafsson +* Randolf Scholz +* Refael Ackermann +* Ruth Comer +* Scott Shambaugh +* Sean Smith +* Thomas A Caswell +* Tim Hoffmann + +GitHub issues and pull requests: + +Pull Requests (45): + +* :ghpull:`28687`: BLD: Include MSVCP140 runtime statically +* :ghpull:`28679`: Run delvewheel with path to required msvcp140.dll +* :ghpull:`28695`: Backport PR #27797 on branch v3.9.x (DOC: Use video files for saving animations) +* :ghpull:`28688`: Backport PR #28293 and #28668: Enable 3.13 wheels and bump cibuildwheel +* :ghpull:`27797`: DOC: Use video files for saving animations +* :ghpull:`28692`: Backport PR #28632 on branch v3.9.x (DOC: Tell sphinx-gallery to link mpl_toolkits from our build) +* :ghpull:`28632`: DOC: Tell sphinx-gallery to link mpl_toolkits from our build +* :ghpull:`28668`: Bump the actions group with 2 updates +* :ghpull:`28686`: Backport PR #28682 on branch v3.9.x (Fix warnings from mingw compilers) +* :ghpull:`28682`: Fix warnings from mingw compilers +* :ghpull:`28676`: Backport PR #28577 on branch v3.9.x (Copy all internals from initial Tick to lazy ones) +* :ghpull:`28577`: Copy all internals from initial Tick to lazy ones +* :ghpull:`28674`: Backport PR #28650 on branch v3.9.x (remove out of date todos on animation.py) +* :ghpull:`28650`: remove out of date todos on animation.py +* :ghpull:`28656`: Backport PR #28649 on branch v3.9.x (FIX: improve formatting of image values in cases of singular norms) +* :ghpull:`28665`: Backport PR #28546 on branch v3.9.x (DOC: Clarify/simplify example of multiple images with one colorbar) +* :ghpull:`28649`: FIX: improve formatting of image values in cases of singular norms +* :ghpull:`28635`: BLD: windows wheels +* :ghpull:`28645`: Backport PR #28644 on branch v3.9.x (DOC: Fix matching for version switcher) +* :ghpull:`28640`: Backport PR #28634 on branch v3.9.x (Closed open div tag in color.ColorMap._repr_html_) +* :ghpull:`28634`: Closed open div tag in color.ColorMap._repr_html_ +* :ghpull:`28636`: Backport PR #28625 on branch v3.9.x (added typing_extensions.Self to _AxesBase.twinx) +* :ghpull:`28625`: added typing_extensions.Self to _AxesBase.twinx +* :ghpull:`28622`: Backport PR #28621 on branch v3.9.x (TYP: Fix a typo in animation.pyi) +* :ghpull:`28621`: TYP: Fix a typo in animation.pyi +* :ghpull:`28605`: Backport PR #28604 on branch v3.9.x (cycler signature update.) +* :ghpull:`28604`: cycler signature update. +* :ghpull:`28598`: Pin PyQt6 back on Ubuntu 20.04 +* :ghpull:`28596`: Backport PR #28518 on branch v3.9.x ([TYP] Fix overload of ``pyplot.subplots``) +* :ghpull:`28518`: [TYP] Fix overload of ``pyplot.subplots`` +* :ghpull:`28591`: Backport PR #28580 on branch v3.9.x (Bump actions/attest-build-provenance from 1.3.2 to 1.3.3 in the actions group) +* :ghpull:`28580`: Bump actions/attest-build-provenance from 1.3.2 to 1.3.3 in the actions group +* :ghpull:`28586`: Backport PR #28582 on branch v3.9.x (FIX: make sticky edge tolerance relative to data range) +* :ghpull:`28582`: FIX: make sticky edge tolerance relative to data range +* :ghpull:`28572`: Backport PR #28571 on branch v3.9.x (DOC: Add version directive to hatch parameter in stackplot) +* :ghpull:`28571`: DOC: Add version directive to hatch parameter in stackplot +* :ghpull:`28564`: Backport PR #28534 on branch v3.9.x ([BLD] Fix WSL build warning) +* :ghpull:`28563`: Backport PR #28526 on branch v3.9.x (Bump pypa/cibuildwheel from 2.19.1 to 2.19.2 in the actions group) +* :ghpull:`28534`: [BLD] Fix WSL build warning +* :ghpull:`28526`: Bump pypa/cibuildwheel from 2.19.1 to 2.19.2 in the actions group +* :ghpull:`28552`: Backport PR #28541 on branch v3.9.x (MNT: be more careful about disk I/O failures when writing font cache) +* :ghpull:`28541`: MNT: be more careful about disk I/O failures when writing font cache +* :ghpull:`28524`: Backport PR #28523 on branch v3.9.x (Fix value error when set widget size to zero while using FigureCanvasQT ) +* :ghpull:`28523`: Fix value error when set widget size to zero while using FigureCanvasQT +* :ghpull:`28519`: Backport PR #28517 on branch v3.9.x (DOC: better cross referencing for animations) + +Issues (9): + +* :ghissue:`28551`: [Bug]: Possible issue with Matplotlib 3.9.1 wheel on Windows only +* :ghissue:`28250`: [Doc]: Sphinx gallery links mispointed for Axes3D methods +* :ghissue:`28574`: [Bug]: Nondeterministic behavior with subplot spacing and constrained layout +* :ghissue:`28626`: [Doc]: Remove old TODO's from animation.py +* :ghissue:`28648`: [Bug]: format_image_data on an image of only zeros produces a large number of zeros +* :ghissue:`28624`: [Bug]: Bad type hint in ``_AxesBase.twinx()`` +* :ghissue:`28567`: [Bug]: sticky edge related changes for datetime plots +* :ghissue:`28533`: [Doc]: Stackplot hatch functionality has version dependencies +* :ghissue:`28538`: [Bug]: Permission denied when importing matplotlib.pyplot diff --git a/doc/users/release_notes.rst b/doc/users/release_notes.rst index 74bc0f13bf1f..010f9b7534bc 100644 --- a/doc/users/release_notes.rst +++ b/doc/users/release_notes.rst @@ -23,6 +23,7 @@ Version 3.9 ../api/prev_api_changes/api_changes_3.9.1.rst ../api/prev_api_changes/api_changes_3.9.0.rst github_stats.rst + prev_whats_new/github_stats_3.9.2.rst prev_whats_new/github_stats_3.9.1.rst prev_whats_new/github_stats_3.9.0.rst From 3ac0aea8be540028cb2510dabb43b290d15b503d Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 30 Nov 2024 03:33:58 -0500 Subject: [PATCH 49/49] REL: 3.9.3 This is the third bugfix release of the 3.9.x series. This release contains several bug-fixes and adjustments: - Fix `axline` with extremely small slopes - Fix `axline` with non-linear axis scales - Fix `minimumSizeHint` with Qt backend - Fix config directory usage when it's behind a symlink - Fix draggable legend when blitting is enabled - Fix high CPU utilization in the `macosx` backend - Fix multiple hatch `edgecolors` passed to `contourf` - Improve compatibility with `pytest` 8.2.0