From 7e5cc665d9d8e67732fbd41cc654a614f2fb45bd Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 30 Aug 2023 16:51:01 -0400 Subject: [PATCH 1/3] TYP: Fix types of errorbar *lims arguments --- lib/matplotlib/axes/_axes.py | 2 +- lib/matplotlib/axes/_axes.pyi | 8 ++++---- lib/matplotlib/pyplot.py | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 4d5907503f09..db0ffe0aaabd 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -3436,7 +3436,7 @@ def errorbar(self, x, y, yerr=None, xerr=None, If True, will plot the errorbars above the plot symbols. Default is below. - lolims, uplims, xlolims, xuplims : bool, default: False + lolims, uplims, xlolims, xuplims : bool or array-like, default: False These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. *lims*-arguments may be scalars, or array-likes of diff --git a/lib/matplotlib/axes/_axes.pyi b/lib/matplotlib/axes/_axes.pyi index 30c0622b89f5..6eeec5cae7fc 100644 --- a/lib/matplotlib/axes/_axes.pyi +++ b/lib/matplotlib/axes/_axes.pyi @@ -332,10 +332,10 @@ class Axes(_AxesBase): elinewidth: float | None = ..., capsize: float | None = ..., barsabove: bool = ..., - lolims: bool = ..., - uplims: bool = ..., - xlolims: bool = ..., - xuplims: bool = ..., + lolims: bool | ArrayLike = ..., + uplims: bool | ArrayLike = ..., + xlolims: bool | ArrayLike = ..., + xuplims: bool | ArrayLike = ..., errorevery: int | tuple[int, int] = ..., capthick: float | None = ..., *, diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 04fdcbc744c9..95ddd9bd7045 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2961,10 +2961,10 @@ def errorbar( elinewidth: float | None = None, capsize: float | None = None, barsabove: bool = False, - lolims: bool = False, - uplims: bool = False, - xlolims: bool = False, - xuplims: bool = False, + lolims: bool | ArrayLike = False, + uplims: bool | ArrayLike = False, + xlolims: bool | ArrayLike = False, + xuplims: bool | ArrayLike = False, errorevery: int | tuple[int, int] = 1, capthick: float | None = None, *, From fa2304c681bc3e595f6040e9b66a0238c520908c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 30 Aug 2023 20:00:53 -0400 Subject: [PATCH 2/3] TYP: Fix return types of Gcf getters Some return None when there is no figure available. --- lib/matplotlib/_pylab_helpers.pyi | 6 ++++-- lib/matplotlib/pyplot.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/_pylab_helpers.pyi b/lib/matplotlib/_pylab_helpers.pyi index 6e1c8889833f..bdd8cfba3173 100644 --- a/lib/matplotlib/_pylab_helpers.pyi +++ b/lib/matplotlib/_pylab_helpers.pyi @@ -6,7 +6,7 @@ from matplotlib.figure import Figure class Gcf: figs: OrderedDict[int, FigureManagerBase] @classmethod - def get_fig_manager(cls, num: int) -> FigureManagerBase: ... + def get_fig_manager(cls, num: int) -> FigureManagerBase | None: ... @classmethod def destroy(cls, num: int | FigureManagerBase) -> None: ... @classmethod @@ -20,7 +20,9 @@ class Gcf: @classmethod def get_num_fig_managers(cls) -> int: ... @classmethod - def get_active(cls) -> FigureManagerBase: ... + def get_active(cls) -> FigureManagerBase | None: ... + @classmethod + def _set_new_active_manager(cls, manager: FigureManagerBase) -> None: ... @classmethod def set_active(cls, manager: FigureManagerBase) -> None: ... @classmethod diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 95ddd9bd7045..976e997a472b 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -938,7 +938,7 @@ def figure( for hookspecs in rcParams["figure.hooks"]: module_name, dotted_name = hookspecs.split(":") - obj = importlib.import_module(module_name) + obj: Any = importlib.import_module(module_name) for part in dotted_name.split("."): obj = getattr(obj, part) obj(fig) From 6e86bdfa2d3b787c5436db312ac23c67bbeceb69 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 30 Aug 2023 20:58:18 -0400 Subject: [PATCH 3/3] TYP: Accept tuples in Legend handles list Fixes #26639 --- lib/matplotlib/axes/_axes.py | 5 ++++- lib/matplotlib/axes/_axes.pyi | 4 ++-- lib/matplotlib/legend.py | 4 ++-- lib/matplotlib/legend.pyi | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index db0ffe0aaabd..c1ad5956e2cb 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -280,7 +280,7 @@ def legend(self, *args, **kwargs): Parameters ---------- - handles : sequence of `.Artist`, optional + handles : sequence of (`.Artist` or tuple of `.Artist`), optional A list of Artists (lines, patches) to be added to the legend. Use this together with *labels*, if you need full control on what is shown in the legend and the automatic mechanism described above @@ -289,6 +289,9 @@ def legend(self, *args, **kwargs): The length of handles and labels should be the same in this case. If they are not, they are truncated to the smaller length. + If an entry contains a tuple, then the legend handler for all Artists in the + tuple will be placed alongside a single label. + labels : list of str, optional A list of labels to show next to the artists. Use this together with *handles*, if you need full control on what diff --git a/lib/matplotlib/axes/_axes.pyi b/lib/matplotlib/axes/_axes.pyi index 6eeec5cae7fc..96ea087f7eb9 100644 --- a/lib/matplotlib/axes/_axes.pyi +++ b/lib/matplotlib/axes/_axes.pyi @@ -57,9 +57,9 @@ class Axes(_AxesBase): @overload def legend(self) -> Legend: ... @overload - def legend(self, handles: Sequence[Artist], labels: Sequence[str], **kwargs) -> Legend: ... + def legend(self, handles: Sequence[Artist | tuple[Artist, ...]], labels: Sequence[str], **kwargs) -> Legend: ... @overload - def legend(self, *, handles: Sequence[Artist], **kwargs) -> Legend: ... + def legend(self, *, handles: Sequence[Artist | tuple[Artist, ...]], **kwargs) -> Legend: ... @overload def legend(self, labels: Sequence[str], **kwargs) -> Legend: ... @overload diff --git a/lib/matplotlib/legend.py b/lib/matplotlib/legend.py index 18d0ee913237..bdabacdfedbf 100644 --- a/lib/matplotlib/legend.py +++ b/lib/matplotlib/legend.py @@ -401,7 +401,7 @@ def __init__( parent : `~matplotlib.axes.Axes` or `.Figure` The artist that contains the legend. - handles : list of `.Artist` + handles : list of (`.Artist` or tuple of `.Artist`) A list of Artists (lines, patches) to be added to the legend. labels : list of str @@ -1322,7 +1322,7 @@ def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs): Returns ------- - handles : list of `.Artist` + handles : list of (`.Artist` or tuple of `.Artist`) The legend handles. labels : list of str The legend labels. diff --git a/lib/matplotlib/legend.pyi b/lib/matplotlib/legend.pyi index 077aaf672d39..d559b06c5d5d 100644 --- a/lib/matplotlib/legend.pyi +++ b/lib/matplotlib/legend.pyi @@ -52,7 +52,7 @@ class Legend(Artist): def __init__( self, parent: Axes | Figure, - handles: Iterable[Artist], + handles: Iterable[Artist | tuple[Artist, ...]], labels: Iterable[str], *, loc: str | tuple[float, float] | int | None = ...,