From e28630a4e32f1f0f2e43c71f5d5532eb52d1bc99 Mon Sep 17 00:00:00 2001 From: "Takumasa N." Date: Thu, 5 Oct 2023 12:12:04 +0000 Subject: [PATCH 1/5] [TYP] Add overload of `pyplot.subplot` --- lib/matplotlib/pyplot.py | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 7f4aa12c9ed6..ce915d7ccfe4 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1440,6 +1440,79 @@ def subplot(*args, **kwargs) -> Axes: return ax +# NOTE The actual type is `Axes` or `numpy.ndarray`, +# but `numpy.ndarray` does notsupport objects. +# NOTE Since there is no Exclude-type in Python's type hints, it is assumed that +# the overload that matches first will be resolved. +# mypy warns that it is an unsafe overload, so mark it as ignore. +@overload # type: ignore[misc] +def subplots( + nrows: Literal[1] = ..., + ncols: Literal[1] = ..., + *, + sharex: bool | Literal["none", "all", "row", "col"] = ..., + sharey: bool | Literal["none", "all", "row", "col"] = ..., + squeeze: Literal[True] = ..., + width_ratios: Sequence[float] | None = ..., + height_ratios: Sequence[float] | None = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + **fig_kw +) -> tuple[Figure, Axes]: + ... + + +@overload # type: ignore[misc] +def subplots( + nrows: Literal[1] = ..., + ncols: int = ..., + *, + sharex: bool | Literal["none", "all", "row", "col"] = ..., + sharey: bool | Literal["none", "all", "row", "col"] = ..., + squeeze: Literal[True] = ..., + width_ratios: Sequence[float] | None = ..., + height_ratios: Sequence[float] | None = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + **fig_kw +) -> tuple[Figure, Sequence[Axes]]: + ... + + +@overload # type: ignore[misc] +def subplots( + nrows: int = ..., + ncols: Literal[1] = ..., + *, + sharex: bool | Literal["none", "all", "row", "col"] = ..., + sharey: bool | Literal["none", "all", "row", "col"] = ..., + squeeze: Literal[True] = ..., + width_ratios: Sequence[float] | None = ..., + height_ratios: Sequence[float] | None = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + **fig_kw +) -> tuple[Figure, Sequence[Axes]]: + ... + + +@overload # type: ignore[misc] +def subplots( + nrows: int = ..., + ncols: int = ..., + *, + sharex: bool | Literal["none", "all", "row", "col"] = ..., + sharey: bool | Literal["none", "all", "row", "col"] = ..., + squeeze: Literal[False] = ..., + width_ratios: Sequence[float] | None = ..., + height_ratios: Sequence[float] | None = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + **fig_kw +) -> tuple[Figure, Sequence[Sequence[Axes]]]: + ... + + def subplots( nrows: int = 1, ncols: int = 1, *, sharex: bool | Literal["none", "all", "row", "col"] = False, From 8e482823705db0be3f01c62f0e5af40f222852dd Mon Sep 17 00:00:00 2001 From: "Takumasa N." Date: Thu, 5 Oct 2023 23:33:05 +0000 Subject: [PATCH 2/5] [TYP] Change overload of pyplot.subplots --- lib/matplotlib/pyplot.py | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index ce915d7ccfe4..aaa528647358 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1440,11 +1440,6 @@ def subplot(*args, **kwargs) -> Axes: return ax -# NOTE The actual type is `Axes` or `numpy.ndarray`, -# but `numpy.ndarray` does notsupport objects. -# NOTE Since there is no Exclude-type in Python's type hints, it is assumed that -# the overload that matches first will be resolved. -# mypy warns that it is an unsafe overload, so mark it as ignore. @overload # type: ignore[misc] def subplots( nrows: Literal[1] = ..., @@ -1462,54 +1457,37 @@ def subplots( ... -@overload # type: ignore[misc] -def subplots( - nrows: Literal[1] = ..., - ncols: int = ..., - *, - sharex: bool | Literal["none", "all", "row", "col"] = ..., - sharey: bool | Literal["none", "all", "row", "col"] = ..., - squeeze: Literal[True] = ..., - width_ratios: Sequence[float] | None = ..., - height_ratios: Sequence[float] | None = ..., - subplot_kw: dict[str, Any] | None = ..., - gridspec_kw: dict[str, Any] | None = ..., - **fig_kw -) -> tuple[Figure, Sequence[Axes]]: - ... - - @overload # type: ignore[misc] def subplots( nrows: int = ..., - ncols: Literal[1] = ..., + ncols: int = ..., *, sharex: bool | Literal["none", "all", "row", "col"] = ..., sharey: bool | Literal["none", "all", "row", "col"] = ..., - squeeze: Literal[True] = ..., + squeeze: Literal[False] = ..., width_ratios: Sequence[float] | None = ..., height_ratios: Sequence[float] | None = ..., subplot_kw: dict[str, Any] | None = ..., gridspec_kw: dict[str, Any] | None = ..., **fig_kw -) -> tuple[Figure, Sequence[Axes]]: +) -> tuple[Figure, np.ndarray]: # TODO numpy/numpy#24738 ... -@overload # type: ignore[misc] +@overload def subplots( nrows: int = ..., ncols: int = ..., *, sharex: bool | Literal["none", "all", "row", "col"] = ..., sharey: bool | Literal["none", "all", "row", "col"] = ..., - squeeze: Literal[False] = ..., + squeeze: bool = ..., width_ratios: Sequence[float] | None = ..., height_ratios: Sequence[float] | None = ..., subplot_kw: dict[str, Any] | None = ..., gridspec_kw: dict[str, Any] | None = ..., **fig_kw -) -> tuple[Figure, Sequence[Sequence[Axes]]]: +) -> tuple[Figure, Axes | np.ndarray]: ... From 9cd2812c5a6a6ad2ab50edcb9386f671cff615f5 Mon Sep 17 00:00:00 2001 From: Takumasa N Date: Fri, 6 Oct 2023 08:45:16 +0900 Subject: [PATCH 3/5] [TYP] Get rid of the type ignores Co-authored-by: Kyle Sunden --- lib/matplotlib/pyplot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index aaa528647358..b8b38d72686b 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1440,7 +1440,7 @@ def subplot(*args, **kwargs) -> Axes: return ax -@overload # type: ignore[misc] +@overload def subplots( nrows: Literal[1] = ..., ncols: Literal[1] = ..., @@ -1457,14 +1457,14 @@ def subplots( ... -@overload # type: ignore[misc] +@overload def subplots( nrows: int = ..., ncols: int = ..., *, sharex: bool | Literal["none", "all", "row", "col"] = ..., sharey: bool | Literal["none", "all", "row", "col"] = ..., - squeeze: Literal[False] = ..., + squeeze: Literal[False], width_ratios: Sequence[float] | None = ..., height_ratios: Sequence[float] | None = ..., subplot_kw: dict[str, Any] | None = ..., From 9fa7b314791451658dc313b5cd07a846a5733d5d Mon Sep 17 00:00:00 2001 From: Takumasa Nakamura Date: Tue, 14 May 2024 11:49:43 +0900 Subject: [PATCH 4/5] [TYP] Fix overloads of `FigureBase.subplots` --- lib/matplotlib/figure.pyi | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/matplotlib/figure.pyi b/lib/matplotlib/figure.pyi index 687ae9e500d0..7a1ed3e2be85 100644 --- a/lib/matplotlib/figure.pyi +++ b/lib/matplotlib/figure.pyi @@ -1,12 +1,12 @@ from collections.abc import Callable, Hashable, Iterable import os -from typing import Any, IO, Literal, TypeVar, overload +from typing import Any, IO, Literal, Sequence, TypeVar, overload import numpy as np from numpy.typing import ArrayLike from matplotlib.artist import Artist -from matplotlib.axes import Axes, SubplotBase +from matplotlib.axes import Axes from matplotlib.backend_bases import ( FigureCanvasBase, MouseButton, @@ -92,6 +92,20 @@ class FigureBase(Artist): @overload def add_subplot(self, **kwargs) -> Axes: ... @overload + def subplots( + self, + nrows: Literal[1] = ..., + ncols: Literal[1] = ..., + *, + sharex: bool | Literal["none", "all", "row", "col"] = ..., + sharey: bool | Literal["none", "all", "row", "col"] = ..., + squeeze: Literal[True] = ..., + width_ratios: Sequence[float] | None = ..., + height_ratios: Sequence[float] | None = ..., + subplot_kw: dict[str, Any] | None = ..., + gridspec_kw: dict[str, Any] | None = ..., + ) -> Axes: ... + @overload def subplots( self, nrows: int = ..., @@ -100,11 +114,11 @@ class FigureBase(Artist): sharex: bool | Literal["none", "all", "row", "col"] = ..., sharey: bool | Literal["none", "all", "row", "col"] = ..., squeeze: Literal[False], - width_ratios: ArrayLike | None = ..., - height_ratios: ArrayLike | None = ..., + width_ratios: Sequence[float] | None = ..., + height_ratios: Sequence[float] | None = ..., subplot_kw: dict[str, Any] | None = ..., - gridspec_kw: dict[str, Any] | None = ... - ) -> np.ndarray: ... + gridspec_kw: dict[str, Any] | None = ..., + ) -> np.ndarray: ... # TODO numpy/numpy#24738 @overload def subplots( self, @@ -114,11 +128,11 @@ class FigureBase(Artist): sharex: bool | Literal["none", "all", "row", "col"] = ..., sharey: bool | Literal["none", "all", "row", "col"] = ..., squeeze: bool = ..., - width_ratios: ArrayLike | None = ..., - height_ratios: ArrayLike | None = ..., + width_ratios: Sequence[float] | None = ..., + height_ratios: Sequence[float] | None = ..., subplot_kw: dict[str, Any] | None = ..., - gridspec_kw: dict[str, Any] | None = ... - ) -> np.ndarray | SubplotBase | Axes: ... + gridspec_kw: dict[str, Any] | None = ..., + ) -> Axes | np.ndarray: ... def delaxes(self, ax: Axes) -> None: ... def clear(self, keep_observers: bool = ...) -> None: ... def clf(self, keep_observers: bool = ...) -> None: ... From c13996b1ea6840906513e11e128f86f179d4c74d Mon Sep 17 00:00:00 2001 From: Takumasa Nakamura Date: Tue, 14 May 2024 12:07:46 +0900 Subject: [PATCH 5/5] [TYP] Omit `SubplotBase` from `GridSpecBase.subplots` --- lib/matplotlib/gridspec.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/gridspec.pyi b/lib/matplotlib/gridspec.pyi index 1ac1bb0b40e7..b6732ad8fafa 100644 --- a/lib/matplotlib/gridspec.pyi +++ b/lib/matplotlib/gridspec.pyi @@ -54,7 +54,7 @@ class GridSpecBase: sharey: bool | Literal["all", "row", "col", "none"] = ..., squeeze: Literal[True] = ..., subplot_kw: dict[str, Any] | None = ... - ) -> np.ndarray | SubplotBase | Axes: ... + ) -> np.ndarray | Axes: ... class GridSpec(GridSpecBase): left: float | None