Skip to content

Commit 6d662b8

Browse files
authored
TYP: plotting (#55829)
* TYP: plotting * mypy fixup
1 parent ef52fea commit 6d662b8

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

pandas/plotting/_matplotlib/core.py

+42-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from typing import (
1313
TYPE_CHECKING,
1414
Literal,
15+
final,
1516
)
1617
import warnings
1718

@@ -274,6 +275,7 @@ def __init__(
274275

275276
self._validate_color_args()
276277

278+
@final
277279
def _validate_subplots_kwarg(
278280
self, subplots: bool | Sequence[Sequence[str]]
279281
) -> bool | list[tuple[int, ...]]:
@@ -420,6 +422,7 @@ def _validate_color_args(self):
420422
"other or pass 'style' without a color symbol"
421423
)
422424

425+
@final
423426
def _iter_data(self, data=None, keep_index: bool = False, fillna=None):
424427
if data is None:
425428
data = self.data
@@ -445,9 +448,11 @@ def nseries(self) -> int:
445448
else:
446449
return self.data.shape[1]
447450

451+
@final
448452
def draw(self) -> None:
449453
self.plt.draw_if_interactive()
450454

455+
@final
451456
def generate(self) -> None:
452457
self._args_adjust()
453458
self._compute_plot_data()
@@ -465,11 +470,13 @@ def generate(self) -> None:
465470
def _args_adjust(self) -> None:
466471
pass
467472

473+
@final
468474
def _has_plotted_object(self, ax: Axes) -> bool:
469475
"""check whether ax has data"""
470476
return len(ax.lines) != 0 or len(ax.artists) != 0 or len(ax.containers) != 0
471477

472-
def _maybe_right_yaxis(self, ax: Axes, axes_num):
478+
@final
479+
def _maybe_right_yaxis(self, ax: Axes, axes_num: int):
473480
if not self.on_right(axes_num):
474481
# secondary axes may be passed via ax kw
475482
return self._get_ax_layer(ax)
@@ -497,6 +504,7 @@ def _maybe_right_yaxis(self, ax: Axes, axes_num):
497504
new_ax.set_yscale("symlog")
498505
return new_ax
499506

507+
@final
500508
def _setup_subplots(self) -> Figure:
501509
if self.subplots:
502510
naxes = (
@@ -567,6 +575,7 @@ def result(self):
567575
else:
568576
return self.axes[0]
569577

578+
@final
570579
def _convert_to_ndarray(self, data):
571580
# GH31357: categorical columns are processed separately
572581
if isinstance(data.dtype, CategoricalDtype):
@@ -585,6 +594,7 @@ def _convert_to_ndarray(self, data):
585594

586595
return data
587596

597+
@final
588598
def _compute_plot_data(self):
589599
data = self.data
590600

@@ -642,6 +652,7 @@ def _compute_plot_data(self):
642652
def _make_plot(self, fig: Figure):
643653
raise AbstractMethodError(self)
644654

655+
@final
645656
def _add_table(self) -> None:
646657
if self.table is False:
647658
return
@@ -652,6 +663,7 @@ def _add_table(self) -> None:
652663
ax = self._get_ax(0)
653664
tools.table(ax, data)
654665

666+
@final
655667
def _post_plot_logic_common(self, ax, data):
656668
"""Common post process for each axes"""
657669
if self.orientation == "vertical" or self.orientation is None:
@@ -674,6 +686,7 @@ def _post_plot_logic_common(self, ax, data):
674686
def _post_plot_logic(self, ax, data) -> None:
675687
"""Post process for each axes. Overridden in child classes"""
676688

689+
@final
677690
def _adorn_subplots(self, fig: Figure):
678691
"""Common post process unrelated to data"""
679692
if len(self.axes) > 0:
@@ -735,6 +748,7 @@ def _adorn_subplots(self, fig: Figure):
735748
raise ValueError(msg)
736749
self.axes[0].set_title(self.title)
737750

751+
@final
738752
def _apply_axis_properties(
739753
self, axis: Axis, rot=None, fontsize: int | None = None
740754
) -> None:
@@ -764,6 +778,7 @@ def legend_title(self) -> str | None:
764778
stringified = map(pprint_thing, self.data.columns.names)
765779
return ",".join(stringified)
766780

781+
@final
767782
def _mark_right_label(self, label: str, index: int) -> str:
768783
"""
769784
Append ``(right)`` to the label of a line if it's plotted on the right axis.
@@ -774,6 +789,7 @@ def _mark_right_label(self, label: str, index: int) -> str:
774789
label += " (right)"
775790
return label
776791

792+
@final
777793
def _append_legend_handles_labels(self, handle: Artist, label: str) -> None:
778794
"""
779795
Append current handle and label to ``legend_handles`` and ``legend_labels``.
@@ -819,6 +835,7 @@ def _make_legend(self) -> None:
819835
if ax.get_visible():
820836
ax.legend(loc="best")
821837

838+
@final
822839
def _get_ax_legend(self, ax: Axes):
823840
"""
824841
Take in axes and return ax and legend under different scenarios
@@ -834,6 +851,7 @@ def _get_ax_legend(self, ax: Axes):
834851
ax = other_ax
835852
return ax, leg
836853

854+
@final
837855
@cache_readonly
838856
def plt(self):
839857
import matplotlib.pyplot as plt
@@ -842,6 +860,7 @@ def plt(self):
842860

843861
_need_to_set_index = False
844862

863+
@final
845864
def _get_xticks(self, convert_period: bool = False):
846865
index = self.data.index
847866
is_datetype = index.inferred_type in ("datetime", "date", "datetime64", "time")
@@ -896,6 +915,7 @@ def _get_custom_index_name(self):
896915
"""Specify whether xlabel/ylabel should be used to override index name"""
897916
return self.xlabel
898917

918+
@final
899919
def _get_index_name(self) -> str | None:
900920
if isinstance(self.data.index, ABCMultiIndex):
901921
name = self.data.index.names
@@ -915,6 +935,7 @@ def _get_index_name(self) -> str | None:
915935

916936
return name
917937

938+
@final
918939
@classmethod
919940
def _get_ax_layer(cls, ax, primary: bool = True):
920941
"""get left (primary) or right (secondary) axes"""
@@ -923,6 +944,7 @@ def _get_ax_layer(cls, ax, primary: bool = True):
923944
else:
924945
return getattr(ax, "right_ax", ax)
925946

947+
@final
926948
def _col_idx_to_axis_idx(self, col_idx: int) -> int:
927949
"""Return the index of the axis where the column at col_idx should be plotted"""
928950
if isinstance(self.subplots, list):
@@ -936,6 +958,7 @@ def _col_idx_to_axis_idx(self, col_idx: int) -> int:
936958
# subplots is True: one ax per column
937959
return col_idx
938960

961+
@final
939962
def _get_ax(self, i: int):
940963
# get the twinx ax if appropriate
941964
if self.subplots:
@@ -950,6 +973,7 @@ def _get_ax(self, i: int):
950973
ax.get_yaxis().set_visible(True)
951974
return ax
952975

976+
@final
953977
@classmethod
954978
def get_default_ax(cls, ax) -> None:
955979
import matplotlib.pyplot as plt
@@ -959,13 +983,15 @@ def get_default_ax(cls, ax) -> None:
959983
ax = plt.gca()
960984
ax = cls._get_ax_layer(ax)
961985

962-
def on_right(self, i):
986+
@final
987+
def on_right(self, i: int):
963988
if isinstance(self.secondary_y, bool):
964989
return self.secondary_y
965990

966991
if isinstance(self.secondary_y, (tuple, list, np.ndarray, ABCIndex)):
967992
return self.data.columns[i] in self.secondary_y
968993

994+
@final
969995
def _apply_style_colors(self, colors, kwds, col_num, label: str):
970996
"""
971997
Manage style and color based on column number and its label.
@@ -1006,6 +1032,7 @@ def _get_colors(
10061032
color=self.kwds.get(color_kwds),
10071033
)
10081034

1035+
@final
10091036
def _parse_errorbars(self, label, err):
10101037
"""
10111038
Look for error keyword arguments and return the actual errorbar data
@@ -1095,6 +1122,7 @@ def match_labels(data, e):
10951122

10961123
return err
10971124

1125+
@final
10981126
def _get_errorbars(
10991127
self, label=None, index=None, xerr: bool = True, yerr: bool = True
11001128
):
@@ -1116,6 +1144,7 @@ def _get_errorbars(
11161144
errors[kw] = err
11171145
return errors
11181146

1147+
@final
11191148
def _get_subplots(self, fig: Figure):
11201149
from matplotlib.axes import Subplot
11211150

@@ -1125,6 +1154,7 @@ def _get_subplots(self, fig: Figure):
11251154
if (isinstance(ax, Subplot) and ax.get_subplotspec() is not None)
11261155
]
11271156

1157+
@final
11281158
def _get_axes_layout(self, fig: Figure) -> tuple[int, int]:
11291159
axes = self._get_subplots(fig)
11301160
x_set = set()
@@ -1163,17 +1193,20 @@ def __init__(self, data, x, y, **kwargs) -> None:
11631193
self.x = x
11641194
self.y = y
11651195

1196+
@final
11661197
@property
11671198
def nseries(self) -> int:
11681199
return 1
11691200

1201+
@final
11701202
def _post_plot_logic(self, ax: Axes, data) -> None:
11711203
x, y = self.x, self.y
11721204
xlabel = self.xlabel if self.xlabel is not None else pprint_thing(x)
11731205
ylabel = self.ylabel if self.ylabel is not None else pprint_thing(y)
11741206
ax.set_xlabel(xlabel)
11751207
ax.set_ylabel(ylabel)
11761208

1209+
@final
11771210
def _plot_colorbar(self, ax: Axes, *, fig: Figure, **kwds):
11781211
# Addresses issues #10611 and #10678:
11791212
# When plotting scatterplots and hexbinplots in IPython
@@ -1353,10 +1386,12 @@ def __init__(self, data, **kwargs) -> None:
13531386
if "x_compat" in self.kwds:
13541387
self.x_compat = bool(self.kwds.pop("x_compat"))
13551388

1389+
@final
13561390
def _is_ts_plot(self) -> bool:
13571391
# this is slightly deceptive
13581392
return not self.x_compat and self.use_index and self._use_dynamic_x()
13591393

1394+
@final
13601395
def _use_dynamic_x(self):
13611396
return use_dynamic_x(self._get_ax(0), self.data)
13621397

@@ -1424,6 +1459,7 @@ def _plot( # type: ignore[override]
14241459
cls._update_stacker(ax, stacking_id, y)
14251460
return lines
14261461

1462+
@final
14271463
def _ts_plot(self, ax: Axes, x, data, style=None, **kwds):
14281464
# accept x to be consistent with normal plot func,
14291465
# x is not passed to tsplot as it uses data.index as x coordinate
@@ -1444,12 +1480,14 @@ def _ts_plot(self, ax: Axes, x, data, style=None, **kwds):
14441480
format_dateaxis(ax, ax.freq, data.index)
14451481
return lines
14461482

1483+
@final
14471484
def _get_stacking_id(self):
14481485
if self.stacked:
14491486
return id(self.data)
14501487
else:
14511488
return None
14521489

1490+
@final
14531491
@classmethod
14541492
def _initialize_stacker(cls, ax: Axes, stacking_id, n: int) -> None:
14551493
if stacking_id is None:
@@ -1461,6 +1499,7 @@ def _initialize_stacker(cls, ax: Axes, stacking_id, n: int) -> None:
14611499
ax._stacker_pos_prior[stacking_id] = np.zeros(n)
14621500
ax._stacker_neg_prior[stacking_id] = np.zeros(n)
14631501

1502+
@final
14641503
@classmethod
14651504
def _get_stacked_values(cls, ax: Axes, stacking_id, values, label):
14661505
if stacking_id is None:
@@ -1480,6 +1519,7 @@ def _get_stacked_values(cls, ax: Axes, stacking_id, values, label):
14801519
f"Column '{label}' contains both positive and negative values"
14811520
)
14821521

1522+
@final
14831523
@classmethod
14841524
def _update_stacker(cls, ax: Axes, stacking_id, values) -> None:
14851525
if stacking_id is None:

0 commit comments

Comments
 (0)