plotnine 0.15.0a2__py3-none-any.whl → 0.15.0a4__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 (70) hide show
  1. plotnine/_mpl/layout_manager/_layout_tree.py +16 -6
  2. plotnine/_utils/__init__.py +7 -103
  3. plotnine/doctools.py +3 -3
  4. plotnine/geoms/annotate.py +10 -10
  5. plotnine/geoms/annotation_logticks.py +5 -8
  6. plotnine/geoms/annotation_stripes.py +4 -6
  7. plotnine/geoms/geom.py +41 -20
  8. plotnine/geoms/geom_abline.py +3 -2
  9. plotnine/geoms/geom_blank.py +0 -3
  10. plotnine/geoms/geom_boxplot.py +4 -4
  11. plotnine/geoms/geom_crossbar.py +3 -3
  12. plotnine/geoms/geom_dotplot.py +1 -1
  13. plotnine/geoms/geom_errorbar.py +2 -2
  14. plotnine/geoms/geom_errorbarh.py +2 -2
  15. plotnine/geoms/geom_hline.py +3 -2
  16. plotnine/geoms/geom_linerange.py +2 -2
  17. plotnine/geoms/geom_map.py +3 -3
  18. plotnine/geoms/geom_path.py +10 -11
  19. plotnine/geoms/geom_point.py +4 -5
  20. plotnine/geoms/geom_pointrange.py +3 -5
  21. plotnine/geoms/geom_polygon.py +2 -3
  22. plotnine/geoms/geom_raster.py +4 -5
  23. plotnine/geoms/geom_rect.py +3 -4
  24. plotnine/geoms/geom_ribbon.py +7 -7
  25. plotnine/geoms/geom_rug.py +1 -1
  26. plotnine/geoms/geom_segment.py +2 -2
  27. plotnine/geoms/geom_smooth.py +3 -3
  28. plotnine/geoms/geom_step.py +2 -2
  29. plotnine/geoms/geom_text.py +2 -3
  30. plotnine/geoms/geom_violin.py +4 -5
  31. plotnine/geoms/geom_vline.py +3 -2
  32. plotnine/guides/guides.py +1 -1
  33. plotnine/layer.py +20 -12
  34. plotnine/mapping/_eval_environment.py +1 -1
  35. plotnine/mapping/aes.py +75 -45
  36. plotnine/scales/scale_color.py +46 -14
  37. plotnine/scales/scale_continuous.py +4 -3
  38. plotnine/scales/scale_datetime.py +28 -14
  39. plotnine/scales/scale_discrete.py +1 -1
  40. plotnine/scales/scale_xy.py +2 -2
  41. plotnine/stats/smoothers.py +19 -19
  42. plotnine/stats/stat.py +15 -25
  43. plotnine/stats/stat_bin.py +2 -5
  44. plotnine/stats/stat_bin_2d.py +7 -9
  45. plotnine/stats/stat_bindot.py +5 -8
  46. plotnine/stats/stat_boxplot.py +5 -5
  47. plotnine/stats/stat_count.py +5 -9
  48. plotnine/stats/stat_density.py +5 -8
  49. plotnine/stats/stat_density_2d.py +11 -8
  50. plotnine/stats/stat_ecdf.py +6 -5
  51. plotnine/stats/stat_ellipse.py +5 -6
  52. plotnine/stats/stat_function.py +6 -8
  53. plotnine/stats/stat_hull.py +2 -3
  54. plotnine/stats/stat_identity.py +1 -2
  55. plotnine/stats/stat_pointdensity.py +4 -7
  56. plotnine/stats/stat_qq.py +45 -20
  57. plotnine/stats/stat_qq_line.py +15 -11
  58. plotnine/stats/stat_quantile.py +6 -7
  59. plotnine/stats/stat_sina.py +12 -14
  60. plotnine/stats/stat_smooth.py +7 -10
  61. plotnine/stats/stat_sum.py +1 -2
  62. plotnine/stats/stat_summary.py +6 -9
  63. plotnine/stats/stat_summary_bin.py +10 -13
  64. plotnine/stats/stat_unique.py +1 -2
  65. plotnine/stats/stat_ydensity.py +7 -10
  66. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a4.dist-info}/METADATA +4 -4
  67. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a4.dist-info}/RECORD +70 -70
  68. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a4.dist-info}/WHEEL +1 -1
  69. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a4.dist-info}/licenses/LICENSE +0 -0
  70. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a4.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import abc
4
4
  from dataclasses import dataclass
5
5
  from functools import cached_property
6
- from typing import TYPE_CHECKING
6
+ from typing import TYPE_CHECKING, cast
7
7
 
8
8
  import numpy as np
9
9
 
@@ -528,8 +528,9 @@ class ColumnsTree(LayoutTree):
528
528
  if self.bottom_tags_align:
529
529
  return
530
530
 
531
- values = max(self.bottom_tag_heights) - np.array(
532
- self.bottom_tag_heights
531
+ values = cast(
532
+ "Sequence[float]",
533
+ max(self.bottom_tag_heights) - np.array(self.bottom_tag_heights),
533
534
  )
534
535
  for item, value in zip(self.nodes, values):
535
536
  if isinstance(item, LayoutSpaces):
@@ -541,7 +542,10 @@ class ColumnsTree(LayoutTree):
541
542
  if self.top_tags_align:
542
543
  return
543
544
 
544
- values = max(self.top_tag_heights) - np.array(self.top_tag_heights)
545
+ values = cast(
546
+ "Sequence[float]",
547
+ max(self.top_tag_heights) - np.array(self.top_tag_heights),
548
+ )
545
549
  for item, value in zip(self.nodes, values):
546
550
  if isinstance(item, LayoutSpaces):
547
551
  item.t.tag_alignment = value
@@ -776,7 +780,10 @@ class RowsTree(LayoutTree):
776
780
  if self.left_tags_align:
777
781
  return
778
782
 
779
- values = max(self.left_tag_widths) - np.array(self.left_tag_widths)
783
+ values = cast(
784
+ "Sequence[float]",
785
+ max(self.left_tag_widths) - np.array(self.left_tag_widths),
786
+ )
780
787
  for item, value in zip(self.nodes, values):
781
788
  if isinstance(item, LayoutSpaces):
782
789
  item.l.tag_alignment = value
@@ -787,7 +794,10 @@ class RowsTree(LayoutTree):
787
794
  if self.right_tags_align:
788
795
  return
789
796
 
790
- values = max(self.right_tag_widths) - np.array(self.right_tag_widths)
797
+ values = cast(
798
+ "Sequence[float]",
799
+ max(self.right_tag_widths) - np.array(self.right_tag_widths),
800
+ )
791
801
  for item, value in zip(self.nodes, values):
792
802
  if isinstance(item, LayoutSpaces):
793
803
  item.r.tag_alignment = value
@@ -12,9 +12,10 @@ from collections.abc import Iterable, Sequence
12
12
  from contextlib import suppress
13
13
  from copy import deepcopy
14
14
  from dataclasses import field
15
- from typing import TYPE_CHECKING, cast, overload
15
+ from typing import TYPE_CHECKING
16
16
  from warnings import warn
17
17
 
18
+ import mizani._colors.utils as color_utils
18
19
  import numpy as np
19
20
  import pandas as pd
20
21
  from pandas.core.groupby import DataFrameGroupBy
@@ -26,12 +27,10 @@ if TYPE_CHECKING:
26
27
  from typing import Any, Callable, Literal, TypeVar
27
28
 
28
29
  import numpy.typing as npt
29
- from matplotlib.typing import ColorType
30
30
  from typing_extensions import TypeGuard
31
31
 
32
32
  from plotnine.typing import (
33
33
  AnyArrayLike,
34
- AnySeries,
35
34
  DataLike,
36
35
  FloatArray,
37
36
  FloatArrayLike,
@@ -60,6 +59,8 @@ BOX_LOCATIONS: dict[str, tuple[float, float]] = {
60
59
  "centre": (0.5, 0.5),
61
60
  }
62
61
 
62
+ to_rgba = color_utils.to_rgba
63
+
63
64
 
64
65
  def is_scalar(val):
65
66
  """
@@ -346,6 +347,8 @@ def _id_var(x: AnyArrayLike, drop: bool = False) -> list[int]:
346
347
  # NaNs are -1, we give them the highest code
347
348
  nan_code = -1
348
349
  new_nan_code = np.max(x.cat.codes) + 1
350
+ # TODO: We are assuming that x is of type Sequence[int|nan]
351
+ # is that accurate.
349
352
  lst = [val if val != nan_code else new_nan_code for val in x]
350
353
  else:
351
354
  lst = list(x.cat.codes + 1)
@@ -513,7 +516,7 @@ def remove_missing(
513
516
  if finite:
514
517
  lst = [np.inf, -np.inf]
515
518
  to_replace = {v: lst for v in vars}
516
- data.replace(to_replace, np.nan, inplace=True) # pyright: ignore[reportArgumentType,reportCallIssue]
519
+ data.replace(to_replace, np.nan, inplace=True)
517
520
  txt = "non-finite"
518
521
  else:
519
522
  txt = "missing"
@@ -528,105 +531,6 @@ def remove_missing(
528
531
  return data
529
532
 
530
533
 
531
- @overload
532
- def to_rgba(colors: ColorType, alpha: float) -> ColorType: ...
533
-
534
-
535
- @overload
536
- def to_rgba(
537
- colors: Sequence[ColorType], alpha: float
538
- ) -> Sequence[ColorType] | ColorType: ...
539
-
540
-
541
- @overload
542
- def to_rgba(
543
- colors: AnySeries, alpha: AnySeries
544
- ) -> Sequence[ColorType] | ColorType: ...
545
-
546
-
547
- def to_rgba(
548
- colors: Sequence[ColorType] | AnySeries | ColorType,
549
- alpha: float | Sequence[float] | AnySeries,
550
- ) -> Sequence[ColorType] | ColorType:
551
- """
552
- Convert hex colors to rgba values.
553
-
554
- Parameters
555
- ----------
556
- colors : iterable | str
557
- colors to convert
558
- alphas : iterable | float
559
- alpha values
560
-
561
- Returns
562
- -------
563
- out : ndarray | tuple
564
- rgba color(s)
565
-
566
- Notes
567
- -----
568
- Matplotlib plotting functions only accept scalar
569
- alpha values. Hence no two objects with different
570
- alpha values may be plotted in one call. This would
571
- make plots with continuous alpha values innefficient.
572
- However :), the colors can be rgba hex values or
573
- list-likes and the alpha dimension will be respected.
574
- """
575
-
576
- def is_iterable(var):
577
- return np.iterable(var) and not isinstance(var, str)
578
-
579
- def has_alpha(c):
580
- return (isinstance(c, tuple) and len(c) == 4) or (
581
- isinstance(c, str) and len(c) == 9 and c[0] == "#"
582
- )
583
-
584
- def no_color(c):
585
- return c is None or c.lower() in ("none", "")
586
-
587
- def to_rgba_hex(c: ColorType, a: float) -> str:
588
- """
589
- Convert rgb color to rgba hex value
590
-
591
- If color c has an alpha channel, then alpha value
592
- a is ignored
593
- """
594
- from matplotlib.colors import colorConverter, to_hex
595
-
596
- if c in ("None", "none"):
597
- return c
598
-
599
- _has_alpha = has_alpha(c)
600
- c = to_hex(c, keep_alpha=_has_alpha)
601
-
602
- if not _has_alpha:
603
- arr = colorConverter.to_rgba(c, a)
604
- return to_hex(arr, keep_alpha=True)
605
-
606
- return c
607
-
608
- if is_iterable(colors):
609
- colors = cast("Sequence[ColorType]", colors)
610
-
611
- if all(no_color(c) for c in colors):
612
- return "none"
613
-
614
- if isinstance(alpha, (Sequence, pd.Series)):
615
- return [to_rgba_hex(c, a) for c, a in zip(colors, alpha)]
616
- else:
617
- return [to_rgba_hex(c, alpha) for c in colors]
618
- else:
619
- colors = cast("ColorType", colors)
620
-
621
- if no_color(colors):
622
- return colors
623
-
624
- if isinstance(alpha, (Sequence, pd.Series)):
625
- return [to_rgba_hex(colors, a) for a in alpha]
626
- else:
627
- return to_rgba_hex(colors, alpha)
628
-
629
-
630
534
  def groupby_apply(
631
535
  df: pd.DataFrame,
632
536
  cols: str | list[str],
plotnine/doctools.py CHANGED
@@ -71,7 +71,7 @@ STAT_SIGNATURE_TPL = """
71
71
 
72
72
  common_params_doc = {
73
73
  "mapping": """\
74
- Aesthetic mappings created with [aes](:class:`plotnine.mapping.aes`). If \
74
+ Aesthetic mappings created with [aes](:class:`plotnine.mapping.aes.aes`). If \
75
75
  specified and `inherit_aes=True`{.py}, it is combined with the default \
76
76
  mapping for the plot. You must supply mapping if there is no plot mapping.""",
77
77
  "data": """\
@@ -103,7 +103,7 @@ the final image is in vector format.""",
103
103
 
104
104
 
105
105
  GEOM_PARAMS_TPL = """
106
- mapping : ~plotnine.mapping.aes, default=None
106
+ mapping : ~plotnine.mapping.aes.aes, default=None
107
107
  {mapping}
108
108
  {_aesthetics_doc}
109
109
  data : ~pandas.DataFrame, default=None
@@ -124,7 +124,7 @@ raster : bool, default={default_raster}
124
124
  """
125
125
 
126
126
  STAT_PARAMS_TPL = """
127
- mapping : ~plotnine.mapping.aes, default=None
127
+ mapping : ~plotnine.mapping.aes.aes, default=None
128
128
  {mapping}
129
129
  {_aesthetics_doc}
130
130
  data : ~pandas.DataFrame, default=None
@@ -64,16 +64,16 @@ class annotate:
64
64
  def __init__(
65
65
  self,
66
66
  geom: str | type[geom_base_class],
67
- x: float | None = None,
68
- y: float | None = None,
69
- xmin: float | None = None,
70
- xmax: float | None = None,
71
- xend: float | None = None,
72
- xintercept: float | None = None,
73
- ymin: float | None = None,
74
- ymax: float | None = None,
75
- yend: float | None = None,
76
- yintercept: float | None = None,
67
+ x: float | list[float] | None = None,
68
+ y: float | list[float] | None = None,
69
+ xmin: float | list[float] | None = None,
70
+ xmax: float | list[float] | None = None,
71
+ xend: float | list[float] | None = None,
72
+ xintercept: float | list[float] | None = None,
73
+ ymin: float | list[float] | None = None,
74
+ ymax: float | list[float] | None = None,
75
+ yend: float | list[float] | None = None,
76
+ yintercept: float | list[float] | None = None,
77
77
  **kwargs: Any,
78
78
  ):
79
79
  variables = locals()
@@ -46,9 +46,7 @@ class _geom_logticks(geom_rug):
46
46
  }
47
47
  draw_legend = staticmethod(geom_path.draw_legend)
48
48
 
49
- def draw_layer(
50
- self, data: pd.DataFrame, layout: Layout, coord: coord, **params: Any
51
- ):
49
+ def draw_layer(self, data: pd.DataFrame, layout: Layout, coord: coord):
52
50
  """
53
51
  Draw ticks on every panel
54
52
  """
@@ -56,7 +54,7 @@ class _geom_logticks(geom_rug):
56
54
  ploc = pid - 1
57
55
  panel_params = layout.panel_params[ploc]
58
56
  ax = layout.axs[ploc]
59
- self.draw_panel(data, panel_params, coord, ax, **params)
57
+ self.draw_panel(data, panel_params, coord, ax)
60
58
 
61
59
  @staticmethod
62
60
  def _check_log_scale(
@@ -184,8 +182,8 @@ class _geom_logticks(geom_rug):
184
182
  panel_params: panel_view,
185
183
  coord: coord,
186
184
  ax: Axes,
187
- **params: Any,
188
185
  ):
186
+ params = self.params
189
187
  # Any passed data is ignored, the relevant data is created
190
188
  sides = params["sides"]
191
189
  lengths = params["lengths"]
@@ -203,9 +201,8 @@ class _geom_logticks(geom_rug):
203
201
  ):
204
202
  for position, length in zip(tick_positions, lengths):
205
203
  data = pd.DataFrame({axis: position, **_aesthetics})
206
- geom.draw_group(
207
- data, panel_params, coord, ax, length=length, **params
208
- )
204
+ params["length"] = length
205
+ geom.draw_group(data, panel_params, coord, ax, params)
209
206
 
210
207
  if isinstance(coord, coord_flip):
211
208
  tick_range_x = panel_params.y.range
@@ -96,9 +96,7 @@ class _geom_stripes(geom):
96
96
  }
97
97
  draw_legend = staticmethod(geom_polygon.draw_legend)
98
98
 
99
- def draw_layer(
100
- self, data: pd.DataFrame, layout: Layout, coord: coord, **params: Any
101
- ):
99
+ def draw_layer(self, data: pd.DataFrame, layout: Layout, coord: coord):
102
100
  """
103
101
  Draw stripes on every panel
104
102
  """
@@ -106,7 +104,7 @@ class _geom_stripes(geom):
106
104
  ploc = pid - 1
107
105
  panel_params = layout.panel_params[ploc]
108
106
  ax = layout.axs[ploc]
109
- self.draw_group(data, panel_params, coord, ax, **params)
107
+ self.draw_group(data, panel_params, coord, ax, self.params)
110
108
 
111
109
  @staticmethod
112
110
  def draw_group(
@@ -114,7 +112,7 @@ class _geom_stripes(geom):
114
112
  panel_params: panel_view,
115
113
  coord: coord,
116
114
  ax: Axes,
117
- **params: Any,
115
+ params: dict[str, Any],
118
116
  ):
119
117
  extend = params["extend"]
120
118
  fill_range = params["fill_range"]
@@ -195,4 +193,4 @@ class _geom_stripes(geom):
195
193
  }
196
194
  )
197
195
 
198
- return geom_rect.draw_group(data, panel_params, coord, ax, **params)
196
+ return geom_rect.draw_group(data, panel_params, coord, ax, params)
plotnine/geoms/geom.py CHANGED
@@ -7,13 +7,12 @@ from itertools import chain, repeat
7
7
 
8
8
  from .._utils import (
9
9
  data_mapping_as_kwargs,
10
- is_list_like,
11
10
  remove_missing,
12
11
  )
13
12
  from .._utils.registry import Register, Registry
14
13
  from ..exceptions import PlotnineError
15
14
  from ..layer import layer
16
- from ..mapping.aes import is_valid_aesthetic, rename_aesthetics
15
+ from ..mapping.aes import RepeatAesthetic, rename_aesthetics
17
16
  from ..mapping.evaluation import evaluate
18
17
  from ..positions.position import position
19
18
  from ..stats.stat import stat
@@ -171,6 +170,26 @@ class geom(ABC, metaclass=Register):
171
170
 
172
171
  return result
173
172
 
173
+ def setup_params(self, data: pd.DataFrame):
174
+ """
175
+ Override this method to verify and/or adjust parameters
176
+
177
+ Parameters
178
+ ----------
179
+ data :
180
+ Data
181
+ """
182
+
183
+ def setup_aes_params(self, data: pd.DataFrame):
184
+ """
185
+ Override this method to verify and/or adjust aesthetic parameters
186
+
187
+ Parameters
188
+ ----------
189
+ data :
190
+ Data
191
+ """
192
+
174
193
  def setup_data(self, data: pd.DataFrame) -> pd.DataFrame:
175
194
  """
176
195
  Modify the data before drawing takes place
@@ -240,30 +259,33 @@ class geom(ABC, metaclass=Register):
240
259
  data[ae] = evaled[ae]
241
260
 
242
261
  num_panels = len(data["PANEL"].unique()) if "PANEL" in data else 1
262
+ across_panels = num_panels > 1 and not self.params["inherit_aes"]
243
263
 
244
264
  # Aesthetics set as parameters to the geom/stat
245
265
  for ae, value in self.aes_params.items():
246
266
  try:
247
267
  data[ae] = value
248
268
  except ValueError as e:
249
- # sniff out the special cases, like custom
250
- # tupled linetypes, shapes and colors
251
- if is_valid_aesthetic(value, ae):
252
- data[ae] = [value] * len(data)
253
- elif num_panels > 1 and is_list_like(value):
254
- data[ae] = list(chain(*repeat(value, num_panels)))
269
+ # NOTE: Handling of the edgecases in this exception is not
270
+ # foolproof.
271
+ repeat_ae = getattr(RepeatAesthetic, ae, None)
272
+ if across_panels:
273
+ # Adding an annotation/abline/hline/vhline with multiple
274
+ # items across to more than 1 panel
275
+ value = list(chain(*repeat(value, num_panels)))
276
+ data[ae] = value
277
+ elif repeat_ae:
278
+ # Some aesthetics may have valid values that are not
279
+ # scalar. e.g. sequences. For such case, we need to
280
+ # insert a sequence of the same value.
281
+ data[ae] = repeat_ae(value, len(data))
255
282
  else:
256
- msg = (
257
- f"'{value}' does not look like a "
258
- f"valid value for `{ae}`"
259
- )
283
+ msg = f"'{ae}={value}' does not look like a valid value"
260
284
  raise PlotnineError(msg) from e
261
285
 
262
286
  return data
263
287
 
264
- def draw_layer(
265
- self, data: pd.DataFrame, layout: Layout, coord: coord, **params: Any
266
- ):
288
+ def draw_layer(self, data: pd.DataFrame, layout: Layout, coord: coord):
267
289
  """
268
290
  Draw layer across all panels
269
291
 
@@ -289,7 +311,7 @@ class geom(ABC, metaclass=Register):
289
311
  ploc = pdata["PANEL"].iloc[0] - 1
290
312
  panel_params = layout.panel_params[ploc]
291
313
  ax = layout.axs[ploc]
292
- self.draw_panel(pdata, panel_params, coord, ax, **params)
314
+ self.draw_panel(pdata, panel_params, coord, ax)
293
315
 
294
316
  def draw_panel(
295
317
  self,
@@ -297,7 +319,6 @@ class geom(ABC, metaclass=Register):
297
319
  panel_params: panel_view,
298
320
  coord: coord,
299
321
  ax: Axes,
300
- **params: Any,
301
322
  ):
302
323
  """
303
324
  Plot all groups
@@ -331,7 +352,7 @@ class geom(ABC, metaclass=Register):
331
352
  """
332
353
  for _, gdata in data.groupby("group"):
333
354
  gdata.reset_index(inplace=True, drop=True)
334
- self.draw_group(gdata, panel_params, coord, ax, **params)
355
+ self.draw_group(gdata, panel_params, coord, ax, self.params)
335
356
 
336
357
  @staticmethod
337
358
  def draw_group(
@@ -339,7 +360,7 @@ class geom(ABC, metaclass=Register):
339
360
  panel_params: panel_view,
340
361
  coord: coord,
341
362
  ax: Axes,
342
- **params: Any,
363
+ params: dict[str, Any],
343
364
  ):
344
365
  """
345
366
  Plot data belonging to a group.
@@ -376,7 +397,7 @@ class geom(ABC, metaclass=Register):
376
397
  panel_params: panel_view,
377
398
  coord: coord,
378
399
  ax: Axes,
379
- **params: Any,
400
+ params: dict[str, Any],
380
401
  ):
381
402
  """
382
403
  Plot data belonging to a unit.
@@ -102,7 +102,6 @@ class geom_abline(geom):
102
102
  panel_params: panel_view,
103
103
  coord: coord,
104
104
  ax: Axes,
105
- **params: Any,
106
105
  ):
107
106
  """
108
107
  Plot all groups
@@ -116,4 +115,6 @@ class geom_abline(geom):
116
115
 
117
116
  for _, gdata in data.groupby("group"):
118
117
  gdata.reset_index(inplace=True)
119
- geom_segment.draw_group(gdata, panel_params, coord, ax, **params)
118
+ geom_segment.draw_group(
119
+ gdata, panel_params, coord, ax, self.params
120
+ )
@@ -6,8 +6,6 @@ from ..doctools import document
6
6
  from .geom import geom
7
7
 
8
8
  if typing.TYPE_CHECKING:
9
- from typing import Any
10
-
11
9
  import pandas as pd
12
10
  from matplotlib.axes import Axes
13
11
 
@@ -39,7 +37,6 @@ class geom_blank(geom):
39
37
  panel_params: panel_view,
40
38
  coord: coord,
41
39
  ax: Axes,
42
- **params: Any,
43
40
  ):
44
41
  pass
45
42
 
@@ -183,7 +183,7 @@ class geom_boxplot(geom):
183
183
  panel_params: panel_view,
184
184
  coord: coord,
185
185
  ax: Axes,
186
- **params: Any,
186
+ params: dict[str, Any],
187
187
  ):
188
188
  def flat(*args: pd.Series[Any]) -> npt.NDArray[Any]:
189
189
  """Flatten list-likes"""
@@ -245,11 +245,11 @@ class geom_boxplot(geom):
245
245
  outliers["shape"] = outlier_value("shape")
246
246
  outliers["size"] = outlier_value("size")
247
247
  outliers["stroke"] = outlier_value("stroke")
248
- geom_point.draw_group(outliers, panel_params, coord, ax, **params)
248
+ geom_point.draw_group(outliers, panel_params, coord, ax, params)
249
249
 
250
250
  # plot
251
- geom_segment.draw_group(whiskers, panel_params, coord, ax, **params)
252
- geom_crossbar.draw_group(box, panel_params, coord, ax, **params)
251
+ geom_segment.draw_group(whiskers, panel_params, coord, ax, params)
252
+ geom_crossbar.draw_group(box, panel_params, coord, ax, params)
253
253
 
254
254
  @staticmethod
255
255
  def draw_legend(
@@ -78,7 +78,7 @@ class geom_crossbar(geom):
78
78
  panel_params: panel_view,
79
79
  coord: coord,
80
80
  ax: Axes,
81
- **params: Any,
81
+ params: dict[str, Any],
82
82
  ):
83
83
  y = data["y"]
84
84
  xmin = data["xmin"]
@@ -160,8 +160,8 @@ class geom_crossbar(geom):
160
160
  )
161
161
 
162
162
  copy_missing_columns(box, data)
163
- geom_polygon.draw_group(box, panel_params, coord, ax, **params)
164
- geom_segment.draw_group(middle, panel_params, coord, ax, **params)
163
+ geom_polygon.draw_group(box, panel_params, coord, ax, params)
164
+ geom_segment.draw_group(middle, panel_params, coord, ax, params)
165
165
 
166
166
  @staticmethod
167
167
  def draw_legend(
@@ -186,7 +186,7 @@ class geom_dotplot(geom):
186
186
  panel_params: panel_view,
187
187
  coord: coord,
188
188
  ax: Axes,
189
- **params: Any,
189
+ params: dict[str, Any],
190
190
  ):
191
191
  from matplotlib.collections import PatchCollection
192
192
  from matplotlib.patches import Ellipse
@@ -67,7 +67,7 @@ class geom_errorbar(geom):
67
67
  panel_params: panel_view,
68
68
  coord: coord,
69
69
  ax: Axes,
70
- **params: Any,
70
+ params: dict[str, Any],
71
71
  ):
72
72
  f = np.hstack
73
73
  # create (two horizontal bars) + vertical bar
@@ -81,4 +81,4 @@ class geom_errorbar(geom):
81
81
  )
82
82
 
83
83
  copy_missing_columns(bars, data)
84
- geom_segment.draw_group(bars, panel_params, coord, ax, **params)
84
+ geom_segment.draw_group(bars, panel_params, coord, ax, params)
@@ -67,7 +67,7 @@ class geom_errorbarh(geom):
67
67
  panel_params: panel_view,
68
68
  coord: coord,
69
69
  ax: Axes,
70
- **params: Any,
70
+ params: dict[str, Any],
71
71
  ):
72
72
  f = np.hstack
73
73
  # create (two vertical bars) + horizontal bar
@@ -81,4 +81,4 @@ class geom_errorbarh(geom):
81
81
  )
82
82
 
83
83
  copy_missing_columns(bars, data)
84
- geom_segment.draw_group(bars, panel_params, coord, ax, **params)
84
+ geom_segment.draw_group(bars, panel_params, coord, ax, params)
@@ -80,7 +80,6 @@ class geom_hline(geom):
80
80
  panel_params: panel_view,
81
81
  coord: coord,
82
82
  ax: Axes,
83
- **params: Any,
84
83
  ):
85
84
  """
86
85
  Plot all groups
@@ -94,4 +93,6 @@ class geom_hline(geom):
94
93
 
95
94
  for _, gdata in data.groupby("group"):
96
95
  gdata.reset_index(inplace=True)
97
- geom_segment.draw_group(gdata, panel_params, coord, ax, **params)
96
+ geom_segment.draw_group(
97
+ gdata, panel_params, coord, ax, self.params
98
+ )
@@ -49,7 +49,7 @@ class geom_linerange(geom):
49
49
  panel_params: panel_view,
50
50
  coord: coord,
51
51
  ax: Axes,
52
- **params: Any,
52
+ params: dict[str, Any],
53
53
  ):
54
54
  data.eval(
55
55
  """
@@ -59,4 +59,4 @@ class geom_linerange(geom):
59
59
  """,
60
60
  inplace=True,
61
61
  )
62
- geom_segment.draw_group(data, panel_params, coord, ax, **params)
62
+ geom_segment.draw_group(data, panel_params, coord, ax, params)
@@ -119,11 +119,11 @@ class geom_map(geom):
119
119
  panel_params: panel_view,
120
120
  coord: coord,
121
121
  ax: Axes,
122
- **params: Any,
123
122
  ):
124
123
  if not len(data):
125
124
  return
126
125
 
126
+ params = self.params
127
127
  data.loc[data["color"].isna(), "color"] = "none"
128
128
  data.loc[data["fill"].isna(), "fill"] = "none"
129
129
  data["fill"] = to_rgba(data["fill"], data["alpha"])
@@ -153,7 +153,7 @@ class geom_map(geom):
153
153
  for _, gdata in data.groupby("group"):
154
154
  gdata.reset_index(inplace=True, drop=True)
155
155
  gdata.is_copy = None
156
- geom_point.draw_group(gdata, panel_params, coord, ax, **params)
156
+ geom_point.draw_group(gdata, panel_params, coord, ax, params)
157
157
  elif geom_type == "MultiPoint":
158
158
  # Where n is the length of the dataframe (no. of multipoints),
159
159
  # m is the number of all points in all multipoints
@@ -168,7 +168,7 @@ class geom_map(geom):
168
168
  data = data.explode("points", ignore_index=True)
169
169
  data["x"] = [p[0] for p in data["points"]]
170
170
  data["y"] = [p[1] for p in data["points"]]
171
- geom_point.draw_group(data, panel_params, coord, ax, **params)
171
+ geom_point.draw_group(data, panel_params, coord, ax, params)
172
172
  elif geom_type in ("LineString", "MultiLineString"):
173
173
  from matplotlib.collections import LineCollection
174
174