[project] name = "matplotlib" authors = [ {email = "matplotlib-users@python.org"}, {name = "John D. Hunter, Michael Droettboom"} ] description = "Python plotting package" readme = "README.md" license = { file = "LICENSE/LICENSE" } dynamic = ["version"] classifiers=[ "Development Status :: 5 - Production/Stable", "Framework :: Matplotlib", "Intended Audience :: Science/Research", "Intended Audience :: Education", "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", "Topic :: Scientific/Engineering :: Visualization", ] # When updating the list of dependencies, add an api_changes/development # entry and also update the following places: # - the `build` dependency group below # - lib/matplotlib/__init__.py (matplotlib._check_versions()) # - ci/minver-requirements.txt # - doc/devel/dependencies.rst # - environment.yml dependencies = [ "contourpy >= 1.0.1", "cycler >= 0.10", "fonttools >= 4.22.0", "kiwisolver >= 1.3.1", "numpy >= 1.25", "packaging >= 20.0", "pillow >= 9", "pyparsing >= 3", "python-dateutil >= 2.7", ] # Also keep in sync with find_program of meson.build. requires-python = ">=3.11" [project.urls] "Homepage" = "https://matplotlib.org" "Download" = "https://matplotlib.org/stable/install/index.html" "Documentation" = "https://matplotlib.org" "Source Code" = "https://github.com/matplotlib/matplotlib" "Bug Tracker" = "https://github.com/matplotlib/matplotlib/issues" "Forum" = "https://discourse.matplotlib.org/" "Donate" = "https://numfocus.org/donate-to-matplotlib" [build-system] build-backend = "mesonpy" # Also keep in sync with dependency groups below. requires = [ # meson-python 0.17.x breaks symlinks in sdists. You can remove this pin if # you really need it and aren't using an sdist. "meson-python>=0.13.2,!=0.17.*", "pybind11>=2.13.2,!=2.13.3", "setuptools_scm>=7,<10", ] [dependency-groups] build = [ # Should be the same as `[project] dependencies` above. "contourpy >= 1.0.1", "cycler >= 0.10", "fonttools >= 4.22.0", "kiwisolver >= 1.3.1", "numpy >= 1.25", "packaging >= 20.0", "pillow >= 9", "pyparsing >= 3", "python-dateutil >= 2.7", # Should be the same as `[build-system] requires` above. "meson-python>=0.13.1,!=0.17.*", "pybind11>=2.13.2,!=2.13.3", "setuptools_scm>=7,<10", # Not required by us but setuptools_scm without a version, so _if_ # installed, then setuptools_scm 8 requires at least this version. # Unfortunately, we can't do a sort of minimum-if-installed dependency, so # we need to keep this for now until setuptools_scm _fully_ drops # setuptools. "setuptools>=64", ] dev = [ {include-group = "build"}, {include-group = "doc"}, {include-group = "test"}, {include-group = "test-extra"}, "pre-commit", ] # Requirements for building docs # # You will first need a matching Matplotlib installation # e.g (from the Matplotlib root directory) # pip install --group build --no-build-isolation --editable . # # Install the documentation requirements with: # pip install --group doc # doc = [ "sphinx>=5.1.0,!=6.1.2", "colorspacious", "ipython", "ipywidgets", "ipykernel", "numpydoc>=1.0", "mpl-sphinx-theme~=3.10.0", "pyyaml", "PyStemmer", "sphinxcontrib-svg2pdfconverter>=1.1.0", "sphinxcontrib-video>=0.2.1", "sphinx-copybutton", "sphinx-design", "sphinx-gallery[parallel]>=0.17.0", "sphinx-tags>=0.4.0", ] # pip requirements for all the CI builds test = [ "black<27", "certifi", "coverage!=6.3", "psutil; sys_platform != 'cygwin'", "pytest!=4.6.0,!=5.4.0,!=8.1.0", "pytest-cov", "pytest-rerunfailures!=16.0", "pytest-timeout", "pytest-xdist", "pytest-xvfb", "tornado", ] # Extra pip requirements test-extra = [ "ipykernel", # jupyter/nbconvert#1970 for the 7.3 series exclusions "nbconvert[execute]!=6.0.0,!=6.0.1,!=7.3.0,!=7.3.1", "nbformat!=5.0.0,!=5.0.1", "pandas!=0.25.0", "pikepdf", "pytz", "xarray", ] # Extra pip requirements for the GitHub Actions mypy build typing = [ "mypy>=1.14", "typing-extensions>=4.6", # Extra stubs distributed separately from the main pypi package "pandas-stubs", "types-pillow", "types-python-dateutil", "types-psutil", "sphinx", ] [tool.meson-python.args] install = ['--tags=data,python-runtime,runtime'] [tool.setuptools_scm] version_scheme = "release-branch-semver" local_scheme = "node-and-date" parentdir_prefix_version = "matplotlib-" fallback_version = "0.0+UNKNOWN" [tool.isort] known_pydata = "numpy, matplotlib.pyplot" known_firstparty = "matplotlib,mpl_toolkits" sections = "FUTURE,STDLIB,THIRDPARTY,PYDATA,FIRSTPARTY,LOCALFOLDER" force_sort_within_sections = true line_length = 88 [tool.ruff] extend-exclude = [ "build", "doc/gallery", "doc/tutorials", "tools/gh_api.py", ] line-length = 88 [tool.ruff.lint] ignore = [ "D100", "D101", "D102", "D103", "D104", "D105", "D106", "D107", "D200", "D202", "D204", "D205", "D301", "D400", "D401", "D403", "D404", "E266", "E305", "E306", "E721", "E741", "F841", ] preview = true explicit-preview-rules = true select = [ "D", "E", "F", "W", "UP035", # The following error codes require the preview mode to be enabled. "E201", "E202", "E203", "E221", "E251", "E261", "E272", "E302", "E703", ] # The following error codes are not supported by ruff v0.2.0 # They are planned and should be selected once implemented # even if they are deselected by default. # These are primarily whitespace/corrected by autoformatters (which we don't use). # See https://github.com/charliermarsh/ruff/issues/2402 for status on implementation external = [ "E122", ] [tool.ruff.lint.pydocstyle] convention = "numpy" [tool.ruff.lint.per-file-ignores] "*.pyi" = ["E501"] "*.ipynb" = ["E402"] "doc/conf.py" = ["E402"] "galleries/examples/images_contours_and_fields/tricontour_demo.py" = ["E201"] "galleries/examples/images_contours_and_fields/tripcolor_demo.py" = ["E201"] "galleries/examples/images_contours_and_fields/triplot_demo.py" = ["E201"] "galleries/examples/lines_bars_and_markers/marker_reference.py" = ["E402"] "galleries/examples/misc/table_demo.py" = ["E201"] "galleries/examples/subplots_axes_and_figures/demo_constrained_layout.py" = ["E402"] "galleries/examples/text_labels_and_annotations/custom_legends.py" = ["E402"] "galleries/examples/ticks/date_concise_formatter.py" = ["E402"] "galleries/examples/ticks/date_formatters_locators.py" = ["F401"] "galleries/examples/user_interfaces/embedding_in_gtk3_panzoom_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/embedding_in_gtk3_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/embedding_in_gtk4_panzoom_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/embedding_in_gtk4_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/gtk3_spreadsheet_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/gtk4_spreadsheet_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/mpl_with_glade3_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/pylab_with_gtk3_sgskip.py" = ["E402"] "galleries/examples/user_interfaces/pylab_with_gtk4_sgskip.py" = ["E402"] "lib/matplotlib/__init__.py" = ["F822"] "lib/matplotlib/_cm.py" = ["E202", "E203", "E302"] "lib/matplotlib/_mathtext.py" = ["E221"] "lib/matplotlib/_mathtext_data.py" = ["E203"] "lib/matplotlib/backends/backend_template.py" = ["F401"] "lib/matplotlib/pylab.py" = ["F401", "F403"] "lib/matplotlib/tests/test_mathtext.py" = ["E501"] "lib/matplotlib/transforms.py" = ["E201"] "lib/matplotlib/tri/_triinterpolate.py" = ["E201", "E221"] "lib/mpl_toolkits/axes_grid1/axes_size.py" = ["E272"] "lib/mpl_toolkits/axisartist/angle_helper.py" = ["E221"] "lib/mpl_toolkits/mplot3d/proj3d.py" = ["E201"] "galleries/users_explain/quick_start.py" = ["E402"] "galleries/users_explain/artists/patheffects_guide.py" = ["E402"] "galleries/users_explain/artists/transforms_tutorial.py" = ["E402"] "galleries/users_explain/colors/colors.py" = ["E402"] "galleries/tutorials/artists.py" = ["E402"] "galleries/users_explain/axes/constrainedlayout_guide.py" = ["E402"] "galleries/users_explain/axes/legend_guide.py" = ["E402"] "galleries/users_explain/axes/tight_layout_guide.py" = ["E402"] "galleries/users_explain/animations/animations.py" = ["E501"] "galleries/tutorials/pyplot.py" = ["E402", "E501"] "galleries/users_explain/text/annotations.py" = ["E402", "E501"] "galleries/users_explain/text/text_intro.py" = ["E402"] "galleries/users_explain/text/text_props.py" = ["E501"] [tool.mypy] ignore_missing_imports = true enable_error_code = [ "ignore-without-code", "redundant-expr", "truthy-bool", ] exclude = [ #stubtest ".*/matplotlib/(sphinxext|backends|pylab|testing/jpl_units)", #mypy precommit "galleries/", "doc/", "lib/mpl_toolkits/", #removing tests causes errors in backends "lib/matplotlib/tests/", # tinypages is used for testing the sphinx ext, # stubtest will import and run, opening a figure if not excluded ".*/tinypages", # pylab's numpy wildcard imports cause re-def failures since numpy 2.2 "lib/matplotlib/pylab.py", ] files = [ "lib/matplotlib", ] follow_imports = "silent" warn_unreachable = true [tool.rstcheck] ignore_directives = [ # matplotlib.sphinxext.mathmpl "mathmpl", # matplotlib.sphinxext.plot_directive "plot", # sphinxext.math_symbol_table "math_symbol_table", # sphinxext.redirect_from "redirect-from", # sphinx-design "card", "dropdown", "grid", "tab-set", # sphinx-gallery "minigallery", "image-sg", # sphinx.ext.autodoc "automodule", "autoclass", "autofunction", "autodata", "automethod", "autoattribute", "autoproperty", # sphinx.ext.autosummary "autosummary", # sphinx.ext.ifconfig "ifconfig", # sphinx.ext.inheritance_diagram "inheritance-diagram", # sphinx-tags "tags", # include directive is causing attribute errors "include" ] ignore_roles = [ # matplotlib.sphinxext.mathmpl "mathmpl", "math-stix", # matplotlib.sphinxext.roles "rc", # sphinxext.github "ghissue", "ghpull", "ghuser", # sphinx-design "octicon", ] ignore_substitutions = [ "Artist", "Axes", "Axis", "Figure", "release" ] ignore_messages = [ "Hyperlink target \".*\" is not referenced.", "Duplicate implicit target name: \".*\".", "Duplicate explicit target name: \".*\".", # sphinx.ext.intersphinx directives "No role entry for \"external+.*\".", "Unknown interpreted text role \"external+.*\"." ] [tool.pytest.ini_options] # Because tests can be run from an installed copy, most of our Pytest # configuration is in the `pytest_configure` function in # `lib/matplotlib/testing/conftest.py`. minversion = "7.0" testpaths = ["lib"] addopts = [ "--import-mode=importlib", ] [tool.cibuildwheel.pyodide] test-requires = "pytest" test-command = [ # Wheels are built without test images, so copy them into the testing directory. "basedir=$(python -c 'import pathlib, matplotlib; print(pathlib.Path(matplotlib.__file__).parent.parent)')", "cp -a {package}/lib/matplotlib/tests/data $basedir/matplotlib/tests/", """ for subdir in matplotlib mpl_toolkits/axes_grid1 mpl_toolkits/axisartist mpl_toolkits/mplot3d; do cp -a {package}/lib/${subdir}/tests/baseline_images $basedir/${subdir}/tests/ done""", # Test installed, not repository, copy as we aren't using an editable install. """\ pytest -p no:cacheprovider --pyargs \ matplotlib mpl_toolkits.axes_grid1 mpl_toolkits.axisartist mpl_toolkits.mplot3d \ -k 'not test_complex_shaping'""", ] [tool.cibuildwheel.pyodide.environment] # Exceptions are needed for pybind11: # https://github.com/pybind/pybind11/pull/5298 CFLAGS = "-fexceptions" CXXFLAGS = "-fexceptions" LDFLAGS = "-fexceptions"