TYP: plotting._matplotlib (#47311) · pandas-dev/pandas@696e9bd (original) (raw)
1
1
`from future import annotations
`
2
2
``
``
3
`+
from abc import (
`
``
4
`+
ABC,
`
``
5
`+
abstractmethod,
`
``
6
`+
)
`
3
7
`from typing import (
`
4
8
`TYPE_CHECKING,
`
5
9
`Hashable,
`
6
10
`Iterable,
`
``
11
`+
Literal,
`
7
12
`Sequence,
`
8
13
`)
`
9
14
`import warnings
`
10
15
``
11
16
`from matplotlib.artist import Artist
`
12
17
`import numpy as np
`
13
18
``
14
``
`-
from pandas._typing import IndexLabel
`
``
19
`+
from pandas._typing import (
`
``
20
`+
IndexLabel,
`
``
21
`+
PlottingOrientation,
`
``
22
`+
)
`
15
23
`from pandas.errors import AbstractMethodError
`
16
24
`from pandas.util._decorators import cache_readonly
`
17
25
``
`@@ -78,7 +86,7 @@ def _color_in_style(style: str) -> bool:
`
78
86
`return not set(BASE_COLORS).isdisjoint(style)
`
79
87
``
80
88
``
81
``
`-
class MPLPlot:
`
``
89
`+
class MPLPlot(ABC):
`
82
90
`"""
`
83
91
` Base class for assembling a pandas plot using matplotlib
`
84
92
``
`@@ -89,13 +97,17 @@ class MPLPlot:
`
89
97
` """
`
90
98
``
91
99
`@property
`
92
``
`-
def _kind(self):
`
``
100
`+
@abstractmethod
`
``
101
`+
def _kind(self) -> str:
`
93
102
`"""Specify kind str. Must be overridden in child class"""
`
94
103
`raise NotImplementedError
`
95
104
``
96
105
`_layout_type = "vertical"
`
97
106
`_default_rot = 0
`
98
``
`-
orientation: str | None = None
`
``
107
+
``
108
`+
@property
`
``
109
`+
def orientation(self) -> str | None:
`
``
110
`+
return None
`
99
111
``
100
112
`axes: np.ndarray # of Axes objects
`
101
113
``
`@@ -843,7 +855,9 @@ def _get_xticks(self, convert_period: bool = False):
`
843
855
``
844
856
`@classmethod
`
845
857
`@register_pandas_matplotlib_converters
`
846
``
`-
def _plot(cls, ax: Axes, x, y, style=None, is_errorbar: bool = False, **kwds):
`
``
858
`+
def _plot(
`
``
859
`+
cls, ax: Axes, x, y: np.ndarray, style=None, is_errorbar: bool = False, **kwds
`
``
860
`+
):
`
847
861
`mask = isna(y)
`
848
862
`if mask.any():
`
849
863
`y = np.ma.array(y)
`
`@@ -1101,7 +1115,7 @@ def _get_axes_layout(self) -> tuple[int, int]:
`
1101
1115
`return (len(y_set), len(x_set))
`
1102
1116
``
1103
1117
``
1104
``
`-
class PlanePlot(MPLPlot):
`
``
1118
`+
class PlanePlot(MPLPlot, ABC):
`
1105
1119
`"""
`
1106
1120
` Abstract class for plotting on plane, currently scatter and hexbin.
`
1107
1121
` """
`
`@@ -1159,7 +1173,9 @@ def _plot_colorbar(self, ax: Axes, **kwds):
`
1159
1173
``
1160
1174
``
1161
1175
`class ScatterPlot(PlanePlot):
`
1162
``
`-
_kind = "scatter"
`
``
1176
`+
@property
`
``
1177
`+
def _kind(self) -> Literal["scatter"]:
`
``
1178
`+
return "scatter"
`
1163
1179
``
1164
1180
`def init(self, data, x, y, s=None, c=None, **kwargs) -> None:
`
1165
1181
`if s is None:
`
`@@ -1247,7 +1263,9 @@ def _make_plot(self):
`
1247
1263
``
1248
1264
``
1249
1265
`class HexBinPlot(PlanePlot):
`
1250
``
`-
_kind = "hexbin"
`
``
1266
`+
@property
`
``
1267
`+
def _kind(self) -> Literal["hexbin"]:
`
``
1268
`+
return "hexbin"
`
1251
1269
``
1252
1270
`def init(self, data, x, y, C=None, **kwargs) -> None:
`
1253
1271
`super().init(data, x, y, **kwargs)
`
`@@ -1277,9 +1295,15 @@ def _make_legend(self):
`
1277
1295
``
1278
1296
``
1279
1297
`class LinePlot(MPLPlot):
`
1280
``
`-
_kind = "line"
`
1281
1298
`_default_rot = 0
`
1282
``
`-
orientation = "vertical"
`
``
1299
+
``
1300
`+
@property
`
``
1301
`+
def orientation(self) -> PlottingOrientation:
`
``
1302
`+
return "vertical"
`
``
1303
+
``
1304
`+
@property
`
``
1305
`+
def _kind(self) -> Literal["line", "area", "hist", "kde", "box"]:
`
``
1306
`+
return "line"
`
1283
1307
``
1284
1308
`def init(self, data, **kwargs) -> None:
`
1285
1309
`from pandas.plotting import plot_params
`
`@@ -1363,8 +1387,7 @@ def _plot( # type: ignore[override]
`
1363
1387
`cls._update_stacker(ax, stacking_id, y)
`
1364
1388
`return lines
`
1365
1389
``
1366
``
`-
@classmethod
`
1367
``
`-
def _ts_plot(cls, ax: Axes, x, data, style=None, **kwds):
`
``
1390
`+
def _ts_plot(self, ax: Axes, x, data, style=None, **kwds):
`
1368
1391
`# accept x to be consistent with normal plot func,
`
1369
1392
`# x is not passed to tsplot as it uses data.index as x coordinate
`
1370
1393
`# column_num must be in kwds for stacking purpose
`
`@@ -1377,9 +1400,9 @@ def _ts_plot(cls, ax: Axes, x, data, style=None, **kwds):
`
1377
1400
`decorate_axes(ax.left_ax, freq, kwds)
`
1378
1401
`if hasattr(ax, "right_ax"):
`
1379
1402
`decorate_axes(ax.right_ax, freq, kwds)
`
1380
``
`-
ax._plot_data.append((data, cls._kind, kwds))
`
``
1403
`+
ax._plot_data.append((data, self._kind, kwds))
`
1381
1404
``
1382
``
`-
lines = cls._plot(ax, data.index, data.values, style=style, **kwds)
`
``
1405
`+
lines = self._plot(ax, data.index, data.values, style=style, **kwds)
`
1383
1406
`# set date formatter, locators and rescale limits
`
1384
1407
`format_dateaxis(ax, ax.freq, data.index)
`
1385
1408
`return lines
`
`@@ -1471,7 +1494,9 @@ def get_label(i):
`
1471
1494
``
1472
1495
``
1473
1496
`class AreaPlot(LinePlot):
`
1474
``
`-
_kind = "area"
`
``
1497
`+
@property
`
``
1498
`+
def _kind(self) -> Literal["area"]:
`
``
1499
`+
return "area"
`
1475
1500
``
1476
1501
`def init(self, data, **kwargs) -> None:
`
1477
1502
`kwargs.setdefault("stacked", True)
`
`@@ -1544,9 +1569,15 @@ def _post_plot_logic(self, ax: Axes, data):
`
1544
1569
``
1545
1570
``
1546
1571
`class BarPlot(MPLPlot):
`
1547
``
`-
_kind = "bar"
`
``
1572
`+
@property
`
``
1573
`+
def _kind(self) -> Literal["bar", "barh"]:
`
``
1574
`+
return "bar"
`
``
1575
+
1548
1576
`_default_rot = 90
`
1549
``
`-
orientation = "vertical"
`
``
1577
+
``
1578
`+
@property
`
``
1579
`+
def orientation(self) -> PlottingOrientation:
`
``
1580
`+
return "vertical"
`
1550
1581
``
1551
1582
`def init(self, data, **kwargs) -> None:
`
1552
1583
`# we have to treat a series differently than a
`
`@@ -1698,9 +1729,15 @@ def _decorate_ticks(self, ax: Axes, name, ticklabels, start_edge, end_edge):
`
1698
1729
``
1699
1730
``
1700
1731
`class BarhPlot(BarPlot):
`
1701
``
`-
_kind = "barh"
`
``
1732
`+
@property
`
``
1733
`+
def _kind(self) -> Literal["barh"]:
`
``
1734
`+
return "barh"
`
``
1735
+
1702
1736
`_default_rot = 0
`
1703
``
`-
orientation = "horizontal"
`
``
1737
+
``
1738
`+
@property
`
``
1739
`+
def orientation(self) -> Literal["horizontal"]:
`
``
1740
`+
return "horizontal"
`
1704
1741
``
1705
1742
`@property
`
1706
1743
`def _start_base(self):
`
`@@ -1727,7 +1764,10 @@ def _decorate_ticks(self, ax: Axes, name, ticklabels, start_edge, end_edge):
`
1727
1764
``
1728
1765
``
1729
1766
`class PiePlot(MPLPlot):
`
1730
``
`-
_kind = "pie"
`
``
1767
`+
@property
`
``
1768
`+
def _kind(self) -> Literal["pie"]:
`
``
1769
`+
return "pie"
`
``
1770
+
1731
1771
`_layout_type = "horizontal"
`
1732
1772
``
1733
1773
`def init(self, data, kind=None, **kwargs) -> None:
`