plotnine 0.15.2__py3-none-any.whl → 0.16.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. plotnine/_mpl/gridspec.py +50 -6
  2. plotnine/_mpl/layout_manager/__init__.py +2 -5
  3. plotnine/_mpl/layout_manager/_composition_layout_items.py +98 -0
  4. plotnine/_mpl/layout_manager/_composition_side_space.py +461 -0
  5. plotnine/_mpl/layout_manager/_engine.py +19 -58
  6. plotnine/_mpl/layout_manager/_grid.py +94 -0
  7. plotnine/_mpl/layout_manager/_layout_tree.py +402 -817
  8. plotnine/_mpl/layout_manager/{_layout_items.py → _plot_layout_items.py} +55 -278
  9. plotnine/_mpl/layout_manager/{_spaces.py → _plot_side_space.py} +111 -291
  10. plotnine/_mpl/layout_manager/_side_space.py +176 -0
  11. plotnine/_mpl/utils.py +259 -1
  12. plotnine/_utils/__init__.py +23 -3
  13. plotnine/_utils/context.py +1 -1
  14. plotnine/_utils/dataclasses.py +24 -0
  15. plotnine/animation.py +13 -12
  16. plotnine/composition/__init__.py +6 -0
  17. plotnine/composition/_beside.py +13 -11
  18. plotnine/composition/_compose.py +263 -99
  19. plotnine/composition/_plot_annotation.py +75 -0
  20. plotnine/composition/_plot_layout.py +143 -0
  21. plotnine/composition/_plot_spacer.py +1 -1
  22. plotnine/composition/_stack.py +13 -11
  23. plotnine/composition/_types.py +28 -0
  24. plotnine/composition/_wrap.py +60 -0
  25. plotnine/facets/facet.py +9 -12
  26. plotnine/facets/facet_grid.py +2 -2
  27. plotnine/facets/facet_wrap.py +1 -1
  28. plotnine/geoms/geom.py +2 -2
  29. plotnine/geoms/geom_map.py +4 -5
  30. plotnine/geoms/geom_path.py +8 -7
  31. plotnine/geoms/geom_rug.py +6 -10
  32. plotnine/geoms/geom_text.py +5 -5
  33. plotnine/ggplot.py +63 -9
  34. plotnine/guides/guide.py +24 -6
  35. plotnine/guides/guide_colorbar.py +88 -46
  36. plotnine/guides/guide_legend.py +47 -20
  37. plotnine/guides/guides.py +2 -2
  38. plotnine/iapi.py +17 -1
  39. plotnine/scales/scale.py +1 -1
  40. plotnine/stats/binning.py +15 -43
  41. plotnine/stats/smoothers.py +7 -3
  42. plotnine/stats/stat.py +2 -2
  43. plotnine/stats/stat_density_2d.py +10 -6
  44. plotnine/stats/stat_pointdensity.py +8 -1
  45. plotnine/stats/stat_qq.py +5 -5
  46. plotnine/stats/stat_qq_line.py +6 -1
  47. plotnine/stats/stat_sina.py +19 -20
  48. plotnine/stats/stat_summary.py +4 -2
  49. plotnine/stats/stat_summary_bin.py +7 -1
  50. plotnine/themes/elements/element_line.py +2 -0
  51. plotnine/themes/elements/element_text.py +12 -1
  52. plotnine/themes/theme.py +18 -24
  53. plotnine/themes/themeable.py +17 -3
  54. plotnine/typing.py +6 -1
  55. {plotnine-0.15.2.dist-info → plotnine-0.16.0a1.dist-info}/METADATA +2 -2
  56. {plotnine-0.15.2.dist-info → plotnine-0.16.0a1.dist-info}/RECORD +59 -51
  57. plotnine/composition/_plotspec.py +0 -50
  58. {plotnine-0.15.2.dist-info → plotnine-0.16.0a1.dist-info}/WHEEL +0 -0
  59. {plotnine-0.15.2.dist-info → plotnine-0.16.0a1.dist-info}/licenses/LICENSE +0 -0
  60. {plotnine-0.15.2.dist-info → plotnine-0.16.0a1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,143 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from itertools import cycle
5
+ from typing import TYPE_CHECKING, Sequence
6
+
7
+ from ..composition._types import ComposeAddable
8
+
9
+ if TYPE_CHECKING:
10
+ from ._compose import Compose
11
+
12
+
13
+ @dataclass(kw_only=True)
14
+ class plot_layout(ComposeAddable):
15
+ """
16
+ Customise the layout of plots in a composition
17
+ """
18
+
19
+ nrow: int | None = None
20
+ """
21
+ Number of rows
22
+ """
23
+
24
+ ncol: int | None = None
25
+ """
26
+ Number of columns
27
+ """
28
+
29
+ byrow: bool | None = None
30
+ """
31
+ How to place plots into the grid.
32
+ If None or True, they are placed row by row, left to right.
33
+ If False, they are placed column by column, top to bottom.
34
+ """
35
+
36
+ widths: Sequence[float] | None = None
37
+ """
38
+ Relative widths of each column
39
+ """
40
+
41
+ heights: Sequence[float] | None = None
42
+ """
43
+ Relative heights of each column
44
+ """
45
+
46
+ _cmp: Compose = field(init=False, repr=False)
47
+ """
48
+ Composition that this layout is attached to
49
+ """
50
+
51
+ def __radd__(self, cmp: Compose) -> Compose:
52
+ """
53
+ Add plot layout to composition
54
+ """
55
+ cmp.layout = self
56
+ return cmp
57
+
58
+ def _setup(self, cmp: Compose):
59
+ """
60
+ Setup default parameters as they are expected by the layout manager
61
+
62
+ - Ensure nrow and ncol have values
63
+ - Ensure the widths & heights are set and normalised to mean=1
64
+ """
65
+ from . import Beside, Stack
66
+
67
+ # setup nrow & ncol
68
+ if isinstance(cmp, Beside):
69
+ if self.ncol is None:
70
+ self.ncol = len(cmp)
71
+ elif self.ncol < len(cmp):
72
+ raise ValueError(
73
+ "Composition has more items than the layout columns."
74
+ )
75
+ if self.nrow is None:
76
+ self.nrow = 1
77
+ elif isinstance(cmp, Stack):
78
+ if self.nrow is None:
79
+ self.nrow = len(cmp)
80
+ elif self.nrow < len(cmp):
81
+ raise ValueError(
82
+ "Composition has more items than the layout rows."
83
+ )
84
+
85
+ if self.ncol is None:
86
+ self.ncol = 1
87
+ else:
88
+ from plotnine.facets.facet_wrap import wrap_dims
89
+
90
+ self.nrow, self.ncol = wrap_dims(len(cmp), self.nrow, self.ncol)
91
+
92
+ nrow, ncol = self.nrow, self.ncol
93
+
94
+ # byrow
95
+ if self.byrow is None:
96
+ self.byrow = True
97
+
98
+ # setup widths & heights
99
+ ws, hs = self.widths, self.heights
100
+ if ws is None:
101
+ ws = (1 / ncol,) * ncol
102
+ elif len(ws) != ncol:
103
+ ws = repeat(ws, ncol)
104
+
105
+ if hs is None:
106
+ hs = (1 / nrow,) * nrow
107
+ elif len(hs) != nrow:
108
+ hs = repeat(hs, nrow)
109
+
110
+ self.widths = normalise(ws)
111
+ self.heights = normalise(hs)
112
+
113
+ def update(self, other: plot_layout):
114
+ """
115
+ Update this layout with the contents of other
116
+ """
117
+ if other.widths:
118
+ self.widths = other.widths
119
+ if other.heights:
120
+ self.heights = other.heights
121
+ if other.ncol:
122
+ self.ncol = other.ncol
123
+ if other.nrow:
124
+ self.nrow = other.nrow
125
+ if other.byrow is not None:
126
+ self.byrow = other.byrow
127
+
128
+
129
+ def repeat(seq: Sequence[float], n: int) -> list[float]:
130
+ """
131
+ Ensure returned sequence has n values, repeat as necessary
132
+ """
133
+ return [val for _, val in zip(range(n), cycle(seq))]
134
+
135
+
136
+ def normalise(seq: Sequence[float]) -> list[float]:
137
+ """
138
+ Normalise seq so that the mean is 1
139
+ """
140
+ mean = sum(seq) / len(seq)
141
+ if mean == 0:
142
+ raise ValueError("Cannot rescale: mean is zero")
143
+ return [x / mean for x in seq]
@@ -39,7 +39,7 @@ class plot_spacer(ggplot):
39
39
  if fill:
40
40
  self.theme += theme(plot_background=element_rect(fill=fill))
41
41
 
42
- def __add__(self, rhs) -> plot_spacer:
42
+ def __add__(self, rhs) -> plot_spacer: # pyright: ignore[reportIncompatibleMethodOverride]
43
43
  """
44
44
  Add to spacer
45
45
 
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- from dataclasses import dataclass
4
3
  from typing import TYPE_CHECKING
5
4
 
6
5
  from ._compose import Compose
@@ -9,7 +8,6 @@ if TYPE_CHECKING:
9
8
  from plotnine.ggplot import ggplot
10
9
 
11
10
 
12
- @dataclass(repr=False)
13
11
  class Stack(Compose):
14
12
  """
15
13
  Place plots or compositions on top of each other
@@ -26,25 +24,18 @@ class Stack(Compose):
26
24
  See Also
27
25
  --------
28
26
  plotnine.composition.Beside : To arrange plots side by side
27
+ plotnine.composition.Wrap : To arrange plots in a grid
29
28
  plotnine.composition.plot_spacer : To add a blank space between plots
30
29
  plotnine.composition.Compose : For more on composing plots
31
30
  """
32
31
 
33
- @property
34
- def nrow(self) -> int:
35
- return len(self)
36
-
37
- @property
38
- def ncol(self) -> int:
39
- return 1
40
-
41
32
  def __truediv__(self, rhs: ggplot | Compose) -> Compose:
42
33
  """
43
34
  Add rhs as a row
44
35
  """
45
36
  # This is an adjacent div i.e. (DIV | rhs) so we collapse the
46
37
  # operands into a single operation
47
- return Stack([*self, rhs])
38
+ return Stack([*self, rhs]) + self.layout + self.annotation
48
39
 
49
40
  def __or__(self, rhs: ggplot | Compose) -> Compose:
50
41
  """
@@ -53,3 +44,14 @@ class Stack(Compose):
53
44
  from ._beside import Beside
54
45
 
55
46
  return Beside([self, rhs])
47
+
48
+ def __add__(self, rhs):
49
+ """
50
+ Add rhs into the stacking composition
51
+ """
52
+ from plotnine import ggplot
53
+
54
+ if not isinstance(rhs, (ggplot, Compose)):
55
+ return super().__add__(rhs)
56
+
57
+ return self / rhs
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from ._compose import Compose
7
+
8
+
9
+ class ComposeAddable:
10
+ """
11
+ Object that can be added to a ggplot object
12
+ """
13
+
14
+ def __radd__(self, other: Compose) -> Compose:
15
+ """
16
+ Add to compose object
17
+
18
+ Parameters
19
+ ----------
20
+ other :
21
+ Compose object
22
+
23
+ Returns
24
+ -------
25
+ :
26
+ Compose object
27
+ """
28
+ return other
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+
3
+ from ..ggplot import ggplot
4
+ from ._compose import Compose
5
+
6
+
7
+ class Wrap(Compose):
8
+ """
9
+ Wrap plots or compositions into a grid
10
+
11
+ **Usage**
12
+
13
+ plot + plot
14
+ plot + composition
15
+ composition + plot
16
+ composition + composition
17
+
18
+ Typically, you will use this class through the `+` operator.
19
+
20
+ Parameters
21
+ ----------
22
+ items:
23
+ The objects to be arranged (composed)
24
+ nrow:
25
+ Number of rows in the composition
26
+ ncol:
27
+ Number of cols in the composition
28
+
29
+ See Also
30
+ --------
31
+ plotnine.composition.Beside : To arrange plots side by side
32
+ plotnine.composition.Stack : To arrange plots vertically
33
+ plotnine.composition.plot_spacer : To add a blank space between plots
34
+ plotnine.composition.Compose : For more on composing plots
35
+ """
36
+
37
+ def __add__(self, rhs):
38
+ """
39
+ Add rhs into the wrapping composition
40
+ """
41
+ if not isinstance(rhs, (ggplot, Compose)):
42
+ return super().__add__(rhs)
43
+
44
+ return Wrap([*self, rhs]) + self.layout + self.annotation
45
+
46
+ def __or__(self, rhs: ggplot | Compose) -> Compose:
47
+ """
48
+ Add rhs as a column
49
+ """
50
+ from ._beside import Beside
51
+
52
+ return Beside([self, rhs])
53
+
54
+ def __truediv__(self, rhs: ggplot | Compose) -> Compose:
55
+ """
56
+ Add rhs as a row
57
+ """
58
+ from ._stack import Stack
59
+
60
+ return Stack([self, rhs])
plotnine/facets/facet.py CHANGED
@@ -93,7 +93,6 @@ class facet:
93
93
 
94
94
  # Axes
95
95
  axs: list[Axes]
96
- _panels_gridspec: p9GridSpec
97
96
 
98
97
  # ggplot object that the facet belongs to
99
98
  plot: ggplot
@@ -144,15 +143,15 @@ class facet:
144
143
  self.figure = plot.figure
145
144
 
146
145
  if hasattr(plot, "axs"):
147
- self.axs = plot.axs
146
+ gs, self.axs = plot._sub_gridspec, plot.axs
148
147
  else:
149
- self.axs = self._make_axes()
148
+ gs, self.axs = self._make_axes()
150
149
 
151
150
  self.coordinates = plot.coordinates
152
151
  self.theme = plot.theme
153
152
  self.layout.axs = self.axs
154
153
  self.strips = Strips.from_facet(self)
155
- return self.axs
154
+ return gs, self.axs
156
155
 
157
156
  def setup_data(self, data: list[pd.DataFrame]) -> list[pd.DataFrame]:
158
157
  """
@@ -378,7 +377,7 @@ class facet:
378
377
 
379
378
  return result
380
379
 
381
- def _get_panels_gridspec(self) -> p9GridSpec:
380
+ def _make_gridspec(self):
382
381
  """
383
382
  Create gridspec for the panels
384
383
  """
@@ -388,21 +387,19 @@ class facet:
388
387
  self.nrow, self.ncol, self.figure, nest_into=self.plot._gridspec[0]
389
388
  )
390
389
 
391
- def _make_axes(self) -> list[Axes]:
390
+ def _make_axes(self) -> tuple[p9GridSpec, list[Axes]]:
392
391
  """
393
392
  Create and return subplot axes
394
393
  """
394
+
395
395
  num_panels = len(self.layout.layout)
396
396
  axsarr = np.empty((self.nrow, self.ncol), dtype=object)
397
-
398
- self._panels_gridspec = self._get_panels_gridspec()
397
+ gs = self._make_gridspec()
399
398
 
400
399
  # Create axes
401
400
  it = itertools.product(range(self.nrow), range(self.ncol))
402
401
  for i, (row, col) in enumerate(it):
403
- axsarr[row, col] = self.figure.add_subplot(
404
- self._panels_gridspec[i]
405
- )
402
+ axsarr[row, col] = self.figure.add_subplot(gs[i])
406
403
 
407
404
  # Rearrange axes
408
405
  # They are ordered to match the positions in the layout table
@@ -423,7 +420,7 @@ class facet:
423
420
  for ax in axs[num_panels:]:
424
421
  self.figure.delaxes(ax)
425
422
  axs = axs[:num_panels]
426
- return list(axs)
423
+ return gs, list(axs)
427
424
 
428
425
  def _aspect_ratio(self) -> Optional[float]:
429
426
  """
@@ -107,7 +107,7 @@ class facet_grid(facet):
107
107
  self.space = space
108
108
  self.margins = margins
109
109
 
110
- def _get_panels_gridspec(self):
110
+ def _make_gridspec(self):
111
111
  """
112
112
  Create gridspec for the panels
113
113
  """
@@ -189,7 +189,7 @@ class facet_grid(facet):
189
189
 
190
190
  n = len(base)
191
191
  panel = ninteraction(base, drop=True)
192
- panel = pd.Categorical(panel, categories=range(1, n + 1))
192
+ panel = pd.Categorical(panel, categories=range(1, n + 1)) # pyright: ignore[reportArgumentType]
193
193
 
194
194
  if self.rows:
195
195
  rows = ninteraction(base[self.rows], drop=True)
@@ -115,7 +115,7 @@ class facet_wrap(facet):
115
115
 
116
116
  layout = pd.DataFrame(
117
117
  {
118
- "PANEL": pd.Categorical(range(1, n + 1)),
118
+ "PANEL": pd.Categorical(range(1, n + 1)), # pyright: ignore[reportArgumentType]
119
119
  "ROW": row.astype(int),
120
120
  "COL": col.astype(int),
121
121
  }
plotnine/geoms/geom.py CHANGED
@@ -166,10 +166,10 @@ class geom(ABC, metaclass=Register):
166
166
  shallow = {"data", "_kwargs", "environment"}
167
167
  for key, item in old.items():
168
168
  if key in shallow:
169
- new[key] = item
169
+ new[key] = item # pyright: ignore[reportIndexIssue]
170
170
  memo[id(new[key])] = new[key]
171
171
  else:
172
- new[key] = deepcopy(item, memo)
172
+ new[key] = deepcopy(item, memo) # pyright: ignore[reportIndexIssue]
173
173
 
174
174
  return result
175
175
 
@@ -126,18 +126,18 @@ class geom_map(geom):
126
126
  params = self.params
127
127
  data.loc[data["color"].isna(), "color"] = "none"
128
128
  data.loc[data["fill"].isna(), "fill"] = "none"
129
- data["fill"] = to_rgba(data["fill"], data["alpha"])
130
129
 
131
130
  geom_type = data.geometry.iloc[0].geom_type
132
131
  if geom_type in ("Polygon", "MultiPolygon"):
133
132
  from matplotlib.collections import PatchCollection
134
133
 
135
134
  linewidth = data["size"] * SIZE_FACTOR
135
+ fill = to_rgba(data["fill"], data["alpha"])
136
136
  patches = [PolygonPatch(g) for g in data["geometry"]]
137
137
  coll = PatchCollection(
138
138
  patches,
139
139
  edgecolor=data["color"],
140
- facecolor=data["fill"],
140
+ facecolor=fill,
141
141
  linestyle=data["linetype"],
142
142
  linewidth=linewidth,
143
143
  zorder=params["zorder"],
@@ -152,7 +152,6 @@ class geom_map(geom):
152
152
  data["y"] = arr[:, 1]
153
153
  for _, gdata in data.groupby("group"):
154
154
  gdata.reset_index(inplace=True, drop=True)
155
- gdata.is_copy = None
156
155
  geom_point.draw_group(gdata, panel_params, coord, ax, params)
157
156
  elif geom_type == "MultiPoint":
158
157
  # Where n is the length of the dataframe (no. of multipoints),
@@ -173,7 +172,7 @@ class geom_map(geom):
173
172
  from matplotlib.collections import LineCollection
174
173
 
175
174
  linewidth = data["size"] * SIZE_FACTOR
176
- data["color"] = to_rgba(data["color"], data["alpha"])
175
+ color = to_rgba(data["color"], data["alpha"])
177
176
  segments = []
178
177
  for g in data["geometry"]:
179
178
  if g.geom_type == "LineString":
@@ -183,7 +182,7 @@ class geom_map(geom):
183
182
 
184
183
  coll = LineCollection(
185
184
  segments,
186
- edgecolor=data["color"],
185
+ edgecolor=color,
187
186
  linewidth=linewidth,
188
187
  linestyle=data["linetype"],
189
188
  zorder=params["zorder"],
@@ -96,8 +96,9 @@ class geom_path(geom):
96
96
  n2 = len(data)
97
97
 
98
98
  if n2 != n1 and not self.params["na_rm"]:
99
- msg = "geom_path: Removed {} rows containing missing values."
100
- warn(msg.format(n1 - n2), PlotnineWarning)
99
+ geom = self.__class__.__name__
100
+ msg = f"{geom}: Removed {n1 - n2} rows containing missing values."
101
+ warn(msg, PlotnineWarning)
101
102
 
102
103
  return data
103
104
 
@@ -109,8 +110,9 @@ class geom_path(geom):
109
110
  ax: Axes,
110
111
  ):
111
112
  if not any(data["group"].duplicated()):
113
+ geom = self.__class__.__name__
112
114
  warn(
113
- "geom_path: Each group consist of only one "
115
+ f"{geom}: Each group consist of only one "
114
116
  "observation. Do you need to adjust the "
115
117
  "group aesthetic?",
116
118
  PlotnineWarning,
@@ -300,7 +302,7 @@ class arrow:
300
302
  last = self.ends in ("last", "both")
301
303
 
302
304
  data = data.sort_values("group", kind="mergesort")
303
- data["color"] = to_rgba(data["color"], data["alpha"])
305
+ data["color"] = to_rgba(data["color"], data["alpha"]) # pyright: ignore[reportCallIssue,reportArgumentType]
304
306
 
305
307
  if self.type == "open":
306
308
  data["facecolor"] = "none"
@@ -423,9 +425,8 @@ class arrow:
423
425
  # We need the axes dimensions so that we can
424
426
  # compute scaling factors
425
427
  width, height = _axes_get_size_inches(ax)
426
- ranges = coord.range(panel_params)
427
- width_ = np.ptp(ranges.x)
428
- height_ = np.ptp(ranges.y)
428
+ width_ = np.ptp(panel_params.x.range)
429
+ height_ = np.ptp(panel_params.y.range)
429
430
 
430
431
  # scaling factors to prevent skewed arrowheads
431
432
  lx = self.length * width_ / width
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing
3
+ from typing import TYPE_CHECKING, cast
4
4
 
5
5
  import numpy as np
6
6
 
@@ -10,7 +10,7 @@ from ..doctools import document
10
10
  from .geom import geom
11
11
  from .geom_path import geom_path
12
12
 
13
- if typing.TYPE_CHECKING:
13
+ if TYPE_CHECKING:
14
14
  from typing import Any
15
15
 
16
16
  import pandas as pd
@@ -89,30 +89,26 @@ class geom_rug(geom):
89
89
  xheight = (xmax - xmin) * params["length"]
90
90
  yheight = (ymax - ymin) * params["length"]
91
91
 
92
- # Please the type checker
93
- x: FloatArray
94
- y: FloatArray
95
-
96
92
  if has_x:
93
+ x = cast("FloatArray", np.repeat(data["x"].to_numpy(), 2))
94
+
97
95
  if "b" in sides:
98
- x = np.repeat(data["x"].to_numpy(), 2)
99
96
  y = np.tile([ymin, ymin + yheight], n)
100
97
  rugs.extend(make_line_segments(x, y, ispath=False))
101
98
 
102
99
  if "t" in sides:
103
- x = np.repeat(data["x"].to_numpy(), 2)
104
100
  y = np.tile([ymax - yheight, ymax], n)
105
101
  rugs.extend(make_line_segments(x, y, ispath=False))
106
102
 
107
103
  if has_y:
104
+ y = cast("FloatArray", np.repeat(data["y"].to_numpy(), 2))
105
+
108
106
  if "l" in sides:
109
107
  x = np.tile([xmin, xmin + xheight], n)
110
- y = np.repeat(data["y"].to_numpy(), 2)
111
108
  rugs.extend(make_line_segments(x, y, ispath=False))
112
109
 
113
110
  if "r" in sides:
114
111
  x = np.tile([xmax - xheight, xmax], n)
115
- y = np.repeat(data["y"].to_numpy(), 2)
116
112
  rugs.extend(make_line_segments(x, y, ispath=False))
117
113
 
118
114
  color = to_rgba(data["color"], data["alpha"])
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing
4
3
  from contextlib import suppress
4
+ from typing import TYPE_CHECKING, cast
5
5
  from warnings import warn
6
6
 
7
7
  import numpy as np
@@ -12,7 +12,7 @@ from ..exceptions import PlotnineError, PlotnineWarning
12
12
  from ..positions import position_nudge
13
13
  from .geom import geom
14
14
 
15
- if typing.TYPE_CHECKING:
15
+ if TYPE_CHECKING:
16
16
  from typing import Any, Sequence
17
17
 
18
18
  import pandas as pd
@@ -244,7 +244,7 @@ class geom_text(geom):
244
244
  axis=1,
245
245
  inplace=True,
246
246
  )
247
- plot_data["color"] = color
247
+ plot_data["color"] = color # pyright: ignore[reportCallIssue,reportArgumentType]
248
248
  plot_data["zorder"] = zorder
249
249
  plot_data["rasterized"] = params["raster"]
250
250
  plot_data["clip_on"] = True
@@ -255,7 +255,7 @@ class geom_text(geom):
255
255
  fill = to_rgba(data.pop("fill"), data["alpha"])
256
256
  if isinstance(fill, tuple):
257
257
  fill = [list(fill)] * len(data["x"])
258
- plot_data["facecolor"] = fill
258
+ plot_data["facecolor"] = fill # pyright: ignore[reportCallIssue,reportArgumentType]
259
259
 
260
260
  tokens = [params["boxstyle"], f"pad={params['label_padding']}"]
261
261
  if params["boxstyle"] in {"round", "round4"}:
@@ -272,7 +272,7 @@ class geom_text(geom):
272
272
 
273
273
  # For labels add a bbox
274
274
  for i in range(len(data)):
275
- kw: dict[str, Any] = plot_data.iloc[i].to_dict()
275
+ kw = cast("dict[str, Any]", plot_data.iloc[i].to_dict())
276
276
  if draw_label:
277
277
  kw["bbox"] = bbox
278
278
  kw["bbox"]["edgecolor"] = params["boxcolor"] or kw["color"]