Skip to content

Commit 0ab6890

Browse files
committed
ENH: Type the possible str legend locs as Literals
Instead of accepting any str, we only accept as set of predefined literals. For simplicity, we don't distinguish the between allowed positions for Axes legend and figure legend. It's still better to limit the allowed range to the union of both rather than to accept abitrary strings.
1 parent 011d12f commit 0ab6890

File tree

4 files changed

+40
-13
lines changed

4 files changed

+40
-13
lines changed

lib/matplotlib/axes/_axes.pyi

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ from collections.abc import Callable, Iterable, Sequence
3636
from typing import Any, Literal, overload
3737
import numpy as np
3838
from numpy.typing import ArrayLike
39-
from matplotlib.typing import ColorType, MarkerType, LineStyleType
39+
from matplotlib.typing import ColorType, MarkerType, LegendLocType, LineStyleType
4040
import pandas as pd
4141

4242

@@ -65,13 +65,16 @@ class Axes(_AxesBase):
6565
@overload
6666
def legend(self) -> Legend: ...
6767
@overload
68-
def legend(self, handles: Iterable[Artist | tuple[Artist, ...]], labels: Iterable[str], **kwargs) -> Legend: ...
68+
def legend(self, handles: Iterable[Artist | tuple[Artist, ...]], labels: Iterable[str],
69+
*, loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
6970
@overload
70-
def legend(self, *, handles: Iterable[Artist | tuple[Artist, ...]], **kwargs) -> Legend: ...
71+
def legend(self, *, handles: Iterable[Artist | tuple[Artist, ...]],
72+
loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
7173
@overload
72-
def legend(self, labels: Iterable[str], **kwargs) -> Legend: ...
74+
def legend(self, labels: Iterable[str],
75+
*, loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
7376
@overload
74-
def legend(self, **kwargs) -> Legend: ...
77+
def legend(self, *, loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
7578

7679
def inset_axes(
7780
self,

lib/matplotlib/figure.pyi

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ from matplotlib.text import Text
2727
from matplotlib.transforms import Affine2D, Bbox, BboxBase, Transform
2828
from mpl_toolkits.mplot3d import Axes3D
2929

30-
from .typing import ColorType, HashableList
30+
from .typing import ColorType, HashableList, LegendLocType
3131

3232
_T = TypeVar("_T")
3333

@@ -152,13 +152,16 @@ class FigureBase(Artist):
152152
@overload
153153
def legend(self) -> Legend: ...
154154
@overload
155-
def legend(self, handles: Iterable[Artist], labels: Iterable[str], **kwargs) -> Legend: ...
155+
def legend(self, handles: Iterable[Artist], labels: Iterable[str],
156+
*, loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
156157
@overload
157-
def legend(self, *, handles: Iterable[Artist], **kwargs) -> Legend: ...
158+
def legend(self, *, handles: Iterable[Artist],
159+
loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
158160
@overload
159-
def legend(self, labels: Iterable[str], **kwargs) -> Legend: ...
161+
def legend(self, labels: Iterable[str],
162+
*, loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
160163
@overload
161-
def legend(self, **kwargs) -> Legend: ...
164+
def legend(self, *, loc: LegendLocType | None = ..., **kwargs) -> Legend: ...
162165

163166
def text(
164167
self,

lib/matplotlib/legend.pyi

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ from matplotlib.transforms import (
1414
BboxBase,
1515
Transform,
1616
)
17+
from matplotlib.typing import ColorType, LegendLocType
1718

1819

1920
import pathlib
2021
from collections.abc import Iterable
2122
from typing import Any, Literal, overload
22-
from .typing import ColorType
23+
2324

2425
class DraggableLegend(DraggableOffsetBox):
2526
legend: Legend
@@ -55,7 +56,7 @@ class Legend(Artist):
5556
handles: Iterable[Artist | tuple[Artist, ...]],
5657
labels: Iterable[str],
5758
*,
58-
loc: str | tuple[float, float] | int | None = ...,
59+
loc: LegendLocType | None = ...,
5960
numpoints: int | None = ...,
6061
markerscale: float | None = ...,
6162
markerfirst: bool = ...,
@@ -118,7 +119,7 @@ class Legend(Artist):
118119
def get_texts(self) -> list[Text]: ...
119120
def set_alignment(self, alignment: Literal["center", "left", "right"]) -> None: ...
120121
def get_alignment(self) -> Literal["center", "left", "right"]: ...
121-
def set_loc(self, loc: str | tuple[float, float] | int | None = ...) -> None: ...
122+
def set_loc(self, loc: LegendLocType | None = ...) -> None: ...
122123
def set_title(
123124
self, title: str, prop: FontProperties | str | pathlib.Path | None = ...
124125
) -> None: ...

lib/matplotlib/typing.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,23 @@
150150
ResizeEventType,
151151
CloseEventType,
152152
]
153+
154+
LegendLocType: TypeAlias = (
155+
Literal[
156+
# for simplicity, we don't distinguish the between allowed positions for
157+
# Axes legend and figure legend. It's still better to limit the allowed
158+
# range to the union of both rather than to accept arbitrary strings
159+
"upper right", "upper left", "lower left", "lower right",
160+
"right", "center left", "center right", "lower center", "upper center",
161+
"center",
162+
# Axes only
163+
"best",
164+
# Figure only
165+
"outside upper left", "outside upper center", "outside upper right",
166+
"outside right upper", "outside right center", "outside right lower",
167+
"outside lower right", "outside lower center", "outside lower left",
168+
"outside left lower", "outside left center", "outside left upper",
169+
] |
170+
tuple[float, float] |
171+
int
172+
)

0 commit comments

Comments
 (0)