From 4df17b88795a00308afeea7639e4e11e6d77bcdf Mon Sep 17 00:00:00 2001
From: Ruth Comer <10599679+rcomer@users.noreply.github.com>
Date: Sat, 23 May 2026 16:00:16 +0100
Subject: [PATCH 1/2] MNT: bump minimum python to 3.12
---
.appveyor.yml | 2 +-
.github/workflows/cibuildwheel.yml | 20 +------------
.github/workflows/linting.yml | 4 +--
.github/workflows/mypy-stubtest.yml | 4 +--
.github/workflows/tests.yml | 20 ++-----------
azure-pipelines.yml | 5 +---
doc/devel/min_dep_policy.rst | 1 +
doc/devel/testing.rst | 2 +-
doc/install/dependencies.rst | 2 +-
environment.yml | 2 +-
lib/matplotlib/_api/__init__.py | 30 ++++---------------
lib/matplotlib/_api/deprecation.pyi | 5 +---
lib/matplotlib/ft2font.pyi | 9 ++----
.../tests/test_backends_interactive.py | 13 --------
lib/matplotlib/tests/test_cbook.py | 18 +++++------
lib/matplotlib/tests/test_pickle.py | 7 -----
pyproject.toml | 3 +-
tox.ini | 2 +-
18 files changed, 32 insertions(+), 117 deletions(-)
diff --git a/.appveyor.yml b/.appveyor.yml
index 4521bc876a8f..10109c9f80f7 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -28,7 +28,7 @@ environment:
--cov-report= --cov=lib --log-level=DEBUG
matrix:
- - PYTHON_VERSION: "3.11"
+ - PYTHON_VERSION: "3.12"
# We always use a 64-bit machine, but can build x86 distributions
# with the PYTHON_ARCH variable
diff --git a/.github/workflows/cibuildwheel.yml b/.github/workflows/cibuildwheel.yml
index 2bb7f9544902..36ec0e404f1f 100644
--- a/.github/workflows/cibuildwheel.yml
+++ b/.github/workflows/cibuildwheel.yml
@@ -50,7 +50,7 @@ jobs:
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
name: Install Python
with:
- python-version: '3.11'
+ python-version: '3.12'
# Something changed somewhere that prevents the downloaded-at-build-time
# licenses from being included in built wheels, so pre-download them so
@@ -176,24 +176,6 @@ jobs:
CIBW_BUILD: "cp312-*"
CIBW_ARCHS: ${{ matrix.cibw_archs }}
- - name: Build wheels for CPython 3.11
- uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1
- with:
- package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }}
- env:
- CIBW_BUILD: "cp311-*"
- CIBW_ARCHS: ${{ matrix.cibw_archs }}
-
- - name: Build wheels for PyPy
- uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1
- with:
- package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }}
- env:
- CIBW_BUILD: "pp311-*"
- CIBW_ARCHS: ${{ matrix.cibw_archs }}
- CIBW_ENABLE: pypy
- if: matrix.cibw_archs != 'aarch64' && matrix.os != 'windows-latest' && matrix.os != 'windows-11-arm'
-
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cibw-wheels-${{ runner.os }}-${{ matrix.cibw_archs }}
diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml
index 51593f607653..33744048d219 100644
--- a/.github/workflows/linting.yml
+++ b/.github/workflows/linting.yml
@@ -36,7 +36,7 @@ jobs:
- name: Set up Python 3
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
- python-version: '3.11'
+ python-version: '3.12'
- name: Install ruff
run: pip3 install ruff
@@ -66,7 +66,7 @@ jobs:
- name: Set up Python 3
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
- python-version: '3.11'
+ python-version: '3.12'
- name: Install mypy
run: pip3 install --group build --group typing
diff --git a/.github/workflows/mypy-stubtest.yml b/.github/workflows/mypy-stubtest.yml
index 81fcd48462e8..da3ff7610901 100644
--- a/.github/workflows/mypy-stubtest.yml
+++ b/.github/workflows/mypy-stubtest.yml
@@ -19,7 +19,7 @@ jobs:
- name: Set up Python 3
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
- python-version: '3.11'
+ python-version: '3.12'
- name: Set up reviewdog
uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.5.0
@@ -33,7 +33,7 @@ jobs:
run: |
set -o pipefail
tox -e stubtest | \
- sed -e "s!.tox/stubtest/lib/python3.11/site-packages!lib!g" | \
+ sed -e "s!.tox/stubtest/lib/python3.12/site-packages!lib!g" | \
reviewdog \
-efm '%Eerror: %m' \
-efm '%CStub: in file %f:%l' \
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index a3a9def4bd40..442f4facbbb9 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -51,13 +51,13 @@ jobs:
include:
- name-suffix: "(Minimum Versions)"
os: ubuntu-22.04
- python-version: '3.11'
+ python-version: '3.12'
extra-requirements: '-c ci/minver-requirements.txt'
delete-font-cache: true
# https://github.com/matplotlib/matplotlib/issues/29844
pygobject-ver: '<3.52.0'
- os: ubuntu-22.04
- python-version: '3.11'
+ python-version: '3.12'
CFLAGS: "-fno-lto" # Ensure that disabling LTO works.
extra-requirements: '--group test-extra'
# https://github.com/matplotlib/matplotlib/issues/29844
@@ -73,16 +73,10 @@ jobs:
python-version: '3.13t'
# https://github.com/matplotlib/matplotlib/issues/29844
pygobject-ver: '<3.52.0'
- - os: ubuntu-24.04
- python-version: '3.12'
- os: ubuntu-24.04
python-version: '3.14'
- os: ubuntu-24.04-arm
python-version: '3.12'
- - os: macos-14 # This runner is on M1 (arm64) chips.
- python-version: '3.11'
- # https://github.com/matplotlib/matplotlib/issues/29732
- pygobject-ver: '<3.52.0'
- os: macos-14 # This runner is on M1 (arm64) chips.
python-version: '3.12'
# https://github.com/matplotlib/matplotlib/issues/29732
@@ -267,16 +261,6 @@ jobs:
echo 'PyQt5 is available' ||
echo 'PyQt5 is not available'
fi
- # 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.11'
- ]]; then
- python -mpip install --upgrade pyside2 &&
- python -c 'import PySide2.QtCore' &&
- echo 'PySide2 is available' ||
- echo 'PySide2 is not available'
- fi
python -mpip install --upgrade --only-binary :all: pyqt6 &&
python -c 'import PyQt6.QtCore' &&
echo 'PyQt6 is available' ||
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 829a1c7b9005..c8df751f2419 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -49,11 +49,8 @@ stages:
- job: Pytest
strategy:
matrix:
- Windows_py311:
- vmImage: 'windows-2022' # Keep one job pinned to the oldest image
- python.version: '3.11'
Windows_py312:
- vmImage: 'windows-latest'
+ vmImage: 'windows-2022' # Keep one job pinned to the oldest image
python.version: '3.12'
Windows_py313:
vmImage: 'windows-latest'
diff --git a/doc/devel/min_dep_policy.rst b/doc/devel/min_dep_policy.rst
index 517cc872139e..d8e4902fda6c 100644
--- a/doc/devel/min_dep_policy.rst
+++ b/doc/devel/min_dep_policy.rst
@@ -115,6 +115,7 @@ specification of the dependencies.
========== ======== ======
Matplotlib Python NumPy
========== ======== ======
+3.12 3.12 1.25.0
3.11 3.11 1.25.0
`3.10`_ 3.10 1.23.0
`3.9`_ 3.9 1.23.0
diff --git a/doc/devel/testing.rst b/doc/devel/testing.rst
index 990b9d0b6493..27594ffe7dd4 100644
--- a/doc/devel/testing.rst
+++ b/doc/devel/testing.rst
@@ -331,7 +331,7 @@ You can also run tox on a subset of environments:
.. code-block:: bash
- $ tox -e py310,py311
+ $ tox -e py312,py314
Tox processes environments sequentially by default,
which can be slow when testing multiple environments.
diff --git a/doc/install/dependencies.rst b/doc/install/dependencies.rst
index 578fab93ed5a..ad5187cd2d86 100644
--- a/doc/install/dependencies.rst
+++ b/doc/install/dependencies.rst
@@ -20,7 +20,7 @@ When installing through a package manager like ``pip`` or ``conda``, the
mandatory dependencies are automatically installed. This list is mainly for
reference.
-* `Python `_ (>= 3.11)
+* `Python `_ (>= 3.12)
* `contourpy `_ (>= 1.0.1)
* `cycler `_ (>= 0.10.0)
* `dateutil `_ (>= 2.7)
diff --git a/environment.yml b/environment.yml
index 313ab11f7e6f..c546409449fd 100644
--- a/environment.yml
+++ b/environment.yml
@@ -26,7 +26,7 @@ dependencies:
- pygobject
- pyparsing>=3
- pyqt
- - python>=3.11
+ - python>=3.12
- python-dateutil>=2.1
- setuptools_scm<10
- wxpython
diff --git a/lib/matplotlib/_api/__init__.py b/lib/matplotlib/_api/__init__.py
index 444e9c76b5b3..d164f7f6d12a 100644
--- a/lib/matplotlib/_api/__init__.py
+++ b/lib/matplotlib/_api/__init__.py
@@ -14,8 +14,6 @@
import functools
import itertools
import pathlib
-import re
-import sys
import warnings
from .deprecation import ( # noqa: F401
@@ -470,25 +468,9 @@ def warn_external(message, category=None):
warnings.warn`` (or ``functools.partial(warnings.warn, stacklevel=2)``,
etc.).
"""
- kwargs = {}
- if sys.version_info[:2] >= (3, 12):
- # Go to Python's `site-packages` or `lib` from an editable install.
- basedir = pathlib.Path(__file__).parents[2]
- kwargs['skip_file_prefixes'] = (str(basedir / 'matplotlib'),
- str(basedir / 'mpl_toolkits'))
- else:
- frame = sys._getframe()
- for stacklevel in itertools.count(1):
- if frame is None:
- # when called in embedded context may hit frame is None
- kwargs['stacklevel'] = stacklevel
- break
- if not re.match(r"\A(matplotlib|mpl_toolkits)(\Z|\.(?!tests\.))",
- # Work around sphinx-gallery not setting __name__.
- frame.f_globals.get("__name__", "")):
- kwargs['stacklevel'] = stacklevel
- break
- frame = frame.f_back
- # preemptively break reference cycle between locals and the frame
- del frame
- warnings.warn(message, category, **kwargs)
+ # Go to Python's `site-packages` or `lib` from an editable install.
+ basedir = pathlib.Path(__file__).parents[2]
+ skip_file_prefixes = (str(basedir / 'matplotlib'),
+ str(basedir / 'mpl_toolkits'))
+
+ warnings.warn(message, category, skip_file_prefixes=skip_file_prefixes)
diff --git a/lib/matplotlib/_api/deprecation.pyi b/lib/matplotlib/_api/deprecation.pyi
index e050290662d9..30034c0f7f31 100644
--- a/lib/matplotlib/_api/deprecation.pyi
+++ b/lib/matplotlib/_api/deprecation.pyi
@@ -1,9 +1,6 @@
from collections.abc import Callable
import contextlib
-from typing import Any, Literal, ParamSpec, TypedDict, TypeVar, overload
-from typing_extensions import (
- Unpack, # < Py 3.11
-)
+from typing import Any, Literal, ParamSpec, TypedDict, TypeVar, Unpack, overload
_P = ParamSpec("_P")
_R = TypeVar("_R")
diff --git a/lib/matplotlib/ft2font.pyi b/lib/matplotlib/ft2font.pyi
index f8057742b376..ea47811a1822 100644
--- a/lib/matplotlib/ft2font.pyi
+++ b/lib/matplotlib/ft2font.pyi
@@ -1,8 +1,7 @@
+from collections.abc import Buffer
from enum import Enum, Flag
from os import PathLike
-import sys
from typing import BinaryIO, Literal, NewType, NotRequired, TypeAlias, TypedDict, cast, final, overload
-from typing_extensions import Buffer # < Py 3.12
import numpy as np
from numpy.typing import NDArray
@@ -242,8 +241,7 @@ class FT2Font(Buffer):
_kerning_factor: int | None = ...,
_warn_if_used: bool = ...,
) -> None: ...
- if sys.version_info[:2] >= (3, 12):
- def __buffer__(self, /, flags: int) -> memoryview: ...
+ def __buffer__(self, flags: int, /) -> memoryview: ...
def _layout(
self,
text: str,
@@ -348,8 +346,7 @@ class FT2Font(Buffer):
class FT2Image(Buffer):
def __init__(self, width: int, height: int) -> None: ...
def draw_rect_filled(self, x0: int, y0: int, x1: int, y1: int) -> None: ...
- if sys.version_info[:2] >= (3, 12):
- def __buffer__(self, /, flags: int) -> memoryview: ...
+ def __buffer__(self, flags: int, /) -> memoryview: ...
@final
class Glyph:
diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py
index 5d76300054d7..3da5f708cb28 100644
--- a/lib/matplotlib/tests/test_backends_interactive.py
+++ b/lib/matplotlib/tests/test_backends_interactive.py
@@ -326,11 +326,6 @@ def _test_thread_impl():
reason='PyPy does not support Tkinter threading: '
'https://foss.heptapod.net/pypy/pypy/-/issues/1929',
strict=True))
- elif (backend == 'tkagg' and
- ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and
- sys.platform == 'darwin' and sys.version_info[:2] < (3, 11)):
- param.marks.append( # https://github.com/actions/setup-python/issues/649
- pytest.mark.xfail('Tk version mismatch on Azure macOS CI'))
@pytest.mark.parametrize("env", _thread_safe_backends)
@@ -610,14 +605,6 @@ def _test_number_of_draws_script():
elif backend == "wx":
param.marks.append(
pytest.mark.skip("wx does not support blitting"))
- elif (backend == 'tkagg' and
- ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and
- sys.platform == 'darwin' and
- sys.version_info[:2] < (3, 11)
- ):
- param.marks.append( # https://github.com/actions/setup-python/issues/649
- pytest.mark.xfail('Tk version mismatch on Azure macOS CI')
- )
@pytest.mark.parametrize("env", _blit_backends)
diff --git a/lib/matplotlib/tests/test_cbook.py b/lib/matplotlib/tests/test_cbook.py
index 2db0d66ccbb5..0c0373217ea0 100644
--- a/lib/matplotlib/tests/test_cbook.py
+++ b/lib/matplotlib/tests/test_cbook.py
@@ -643,17 +643,13 @@ def get_a(self): return None
def test_warn_external(recwarn):
_api.warn_external("oops")
assert len(recwarn) == 1
- if sys.version_info[:2] >= (3, 12):
- # With Python 3.12, we let Python figure out the stacklevel using the
- # `skip_file_prefixes` argument, which cannot exempt tests, so just confirm
- # the filename is not in the package.
- basedir = pathlib.Path(__file__).parents[2]
- assert not recwarn[0].filename.startswith((str(basedir / 'matplotlib'),
- str(basedir / 'mpl_toolkits')))
- else:
- # On older Python versions, we manually calculated the stacklevel, and had an
- # exception for our own tests.
- assert recwarn[0].filename == __file__
+ # Since Python 3.12, we let Python figure out the stacklevel using the
+ # `skip_file_prefixes` argument, which cannot exempt tests, so just confirm
+ # the filename is not in the package.
+ basedir = pathlib.Path(__file__).parents[2]
+ assert not recwarn[0].filename.startswith((str(basedir / 'matplotlib'),
+ str(basedir / 'mpl_toolkits')))
+
def test_warn_external_frame_embedded_python():
diff --git a/lib/matplotlib/tests/test_pickle.py b/lib/matplotlib/tests/test_pickle.py
index 3494dceffe5d..27111aa29030 100644
--- a/lib/matplotlib/tests/test_pickle.py
+++ b/lib/matplotlib/tests/test_pickle.py
@@ -1,7 +1,6 @@
from io import BytesIO
import ast
import os
-import sys
import pickle
import pickletools
@@ -124,7 +123,6 @@ def test_complete(fig_test, fig_ref):
def _pickle_load_subprocess():
- import os
import pickle
path = os.environ['PICKLE_FILE_PATH']
@@ -318,11 +316,6 @@ def _test_axeswidget_interactive():
pickle.dumps(mpl.widgets.Button(ax, "button"))
-@pytest.mark.xfail( # https://github.com/actions/setup-python/issues/649
- ('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and
- sys.platform == 'darwin' and sys.version_info[:2] < (3, 11),
- reason='Tk version mismatch on Azure macOS CI'
- )
def test_axeswidget_interactive():
subprocess_run_helper(
_test_axeswidget_interactive,
diff --git a/pyproject.toml b/pyproject.toml
index eef7f82fb810..5232a6bdd5aa 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,7 +16,6 @@ classifiers=[
"License :: OSI Approved :: Python Software Foundation License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
@@ -42,7 +41,7 @@ dependencies = [
"python-dateutil >= 2.7",
]
# Also keep in sync with find_program of meson.build.
-requires-python = ">=3.11"
+requires-python = ">=3.12"
[project.urls]
"Homepage" = "https://matplotlib.org"
diff --git a/tox.ini b/tox.ini
index 956e4050cfa9..64c54ed88725 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,7 @@
# and then run "tox" from this directory.
[tox]
-envlist = py311, py312, py313, stubtest
+envlist = py312, py313, py314, stubtest
[testenv]
changedir = /tmp
From 748713eb353a18eb22084205416af0b64b2493b4 Mon Sep 17 00:00:00 2001
From: Ruth Comer <10599679+rcomer@users.noreply.github.com>
Date: Sat, 23 May 2026 16:42:04 +0100
Subject: [PATCH 2/2] MNT: bump minimum numpy to 2.0
---
ci/minver-requirements.txt | 4 ++--
doc/devel/min_dep_policy.rst | 2 +-
doc/install/dependencies.rst | 4 ++--
environment.yml | 4 ++--
galleries/examples/units/basic_units.py | 7 ++-----
lib/matplotlib/tests/test_axes.py | 3 ---
lib/matplotlib/tests/test_contour.py | 4 +---
lib/matplotlib/tests/test_ticker.py | 7 ++-----
lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 4 +---
pyproject.toml | 8 ++++----
10 files changed, 17 insertions(+), 30 deletions(-)
diff --git a/ci/minver-requirements.txt b/ci/minver-requirements.txt
index 3b6aea9e7ca3..6fdcbe5cfafc 100644
--- a/ci/minver-requirements.txt
+++ b/ci/minver-requirements.txt
@@ -1,13 +1,13 @@
# Extra pip requirements for the minimum-version CI run
-contourpy==1.0.1
+contourpy==1.2.1
cycler==0.10
fonttools==4.22.0
importlib-resources==3.2.0
kiwisolver==1.3.2
meson-python==0.13.2
meson==1.1.0
-numpy==1.25.0
+numpy==2.0.0
packaging==20.0
pillow==9.0.1
pyparsing==3.0.0
diff --git a/doc/devel/min_dep_policy.rst b/doc/devel/min_dep_policy.rst
index d8e4902fda6c..f0dc0438c8e4 100644
--- a/doc/devel/min_dep_policy.rst
+++ b/doc/devel/min_dep_policy.rst
@@ -115,7 +115,7 @@ specification of the dependencies.
========== ======== ======
Matplotlib Python NumPy
========== ======== ======
-3.12 3.12 1.25.0
+3.12 3.12 2.0.0
3.11 3.11 1.25.0
`3.10`_ 3.10 1.23.0
`3.9`_ 3.9 1.23.0
diff --git a/doc/install/dependencies.rst b/doc/install/dependencies.rst
index ad5187cd2d86..1b61a8591a5c 100644
--- a/doc/install/dependencies.rst
+++ b/doc/install/dependencies.rst
@@ -21,12 +21,12 @@ mandatory dependencies are automatically installed. This list is mainly for
reference.
* `Python `_ (>= 3.12)
-* `contourpy `_ (>= 1.0.1)
+* `contourpy `_ (>= 1.2.1)
* `cycler `_ (>= 0.10.0)
* `dateutil `_ (>= 2.7)
* `fontTools `_ (>= 4.22.0)
* `kiwisolver `_ (>= 1.3.1)
-* `NumPy `_ (>= 1.25)
+* `NumPy `_ (>= 2.0)
* `packaging `_ (>= 20.0)
* `Pillow `_ (>= 9.0)
* `pyparsing `_ (>= 3)
diff --git a/environment.yml b/environment.yml
index c546409449fd..068bb10588db 100644
--- a/environment.yml
+++ b/environment.yml
@@ -13,14 +13,14 @@ dependencies:
- cairocffi
- c-compiler
- cxx-compiler
- - contourpy>=1.0.1
+ - contourpy>=1.2.1
- cycler>=0.10.0
- fonttools>=4.22.0
- importlib-resources>=3.2.0
- kiwisolver>=1.3.1
- pybind11>=2.13.2
- meson-python>=0.13.1
- - numpy>=1.25
+ - numpy>=2.0
- pillow>=9
- pkg-config
- pygobject
diff --git a/galleries/examples/units/basic_units.py b/galleries/examples/units/basic_units.py
index f7bdcc18b0dc..fe60f44d3677 100644
--- a/galleries/examples/units/basic_units.py
+++ b/galleries/examples/units/basic_units.py
@@ -18,8 +18,6 @@
import itertools
import math
-from packaging.version import parse as parse_version
-
import numpy as np
import matplotlib.ticker as ticker
@@ -170,9 +168,8 @@ def __str__(self):
def __len__(self):
return len(self.value)
- if parse_version(np.__version__) >= parse_version('1.20'):
- def __getitem__(self, key):
- return TaggedValue(self.value[key], self.unit)
+ def __getitem__(self, key):
+ return TaggedValue(self.value[key], self.unit)
def __iter__(self):
# Return a generator expression rather than use `yield`, so that
diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py
index 209593aee15e..43babac20897 100644
--- a/lib/matplotlib/tests/test_axes.py
+++ b/lib/matplotlib/tests/test_axes.py
@@ -1609,9 +1609,6 @@ def test_pcolor_log_scale(fig_test, fig_ref):
when using pcolor.
"""
x = np.linspace(0, 1, 11)
- # Ensuring second x value always falls slightly above 0.1 prevents flakiness with
- # numpy v1 #30882. This can be removed once we require numpy >= 2.
- x[1] += 0.00001
y = np.linspace(1, 2, 5)
X, Y = np.meshgrid(x, y)
C = X[:-1, :-1] + Y[:-1, :-1]
diff --git a/lib/matplotlib/tests/test_contour.py b/lib/matplotlib/tests/test_contour.py
index 3c810b026fce..53921e70046c 100644
--- a/lib/matplotlib/tests/test_contour.py
+++ b/lib/matplotlib/tests/test_contour.py
@@ -11,7 +11,6 @@
from matplotlib.colors import LogNorm, same_color
import matplotlib.patches as mpatches
from matplotlib.testing.decorators import check_figures_equal, image_comparison
-from packaging.version import parse as parse_version
import pytest
@@ -257,8 +256,7 @@ def test_contour_datetime_axis():
@image_comparison(['contour_test_label_transforms.png'],
remove_text=True, style='mpl20',
- tol=1 if parse_version(np.version.version).major < 2 else
- 0 if platform.machine() == 'x86_64' else 0.005)
+ tol=0 if platform.machine() == 'x86_64' else 0.005)
def test_labels():
# Adapted from pylab_examples example code: contour_demo.py
# see issues #2475, #2843, and #2818 for explanation
diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py
index 0d01677acc8c..c595e9989822 100644
--- a/lib/matplotlib/tests/test_ticker.py
+++ b/lib/matplotlib/tests/test_ticker.py
@@ -6,7 +6,7 @@
from packaging.version import parse as parse_version
import numpy as np
-from numpy.testing import assert_almost_equal, assert_array_equal, assert_allclose
+from numpy.testing import assert_almost_equal, assert_array_equal
import pytest
import matplotlib as mpl
@@ -1951,10 +1951,7 @@ def test_bad_locator_subs(sub):
@mpl.style.context('default')
def test_small_range_loglocator(numticks, lims, ticks):
ll = mticker.LogLocator(numticks=numticks)
- if parse_version(np.version.version).major < 2:
- assert_allclose(ll.tick_values(*lims), ticks, rtol=2e-16)
- else:
- assert_array_equal(ll.tick_values(*lims), ticks)
+ assert_array_equal(ll.tick_values(*lims), ticks)
@mpl.style.context('default')
diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py
index 2a5593a641c9..4baea580df47 100644
--- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py
+++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py
@@ -3,7 +3,6 @@
import platform
import sys
-from packaging.version import parse as parse_version
import pytest
from mpl_toolkits.mplot3d import Axes3D, axes3d, proj3d, art3d
@@ -182,8 +181,7 @@ def test_bar3d_shaded():
fig.canvas.draw()
-@mpl3d_image_comparison(['bar3d_notshaded.png'], style='mpl20',
- tol=0.01 if parse_version(np.version.version).major < 2 else 0)
+@mpl3d_image_comparison(['bar3d_notshaded.png'], style='mpl20')
def test_bar3d_notshaded():
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
diff --git a/pyproject.toml b/pyproject.toml
index 5232a6bdd5aa..1a5d42c1b782 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -30,11 +30,11 @@ classifiers=[
# - doc/devel/dependencies.rst
# - environment.yml
dependencies = [
- "contourpy >= 1.0.1",
+ "contourpy >= 1.2.1",
"cycler >= 0.10",
"fonttools >= 4.22.0",
"kiwisolver >= 1.3.1",
- "numpy >= 1.25",
+ "numpy >= 2.0",
"packaging >= 20.0",
"pillow >= 9",
"pyparsing >= 3",
@@ -68,11 +68,11 @@ requires = [
[dependency-groups]
build = [
# Should be the same as `[project] dependencies` above.
- "contourpy >= 1.0.1",
+ "contourpy >= 1.2.1",
"cycler >= 0.10",
"fonttools >= 4.22.0",
"kiwisolver >= 1.3.1",
- "numpy >= 1.25",
+ "numpy >= 2.0",
"packaging >= 20.0",
"pillow >= 9",
"pyparsing >= 3",