plotnine 0.15.0a2__py3-none-any.whl → 0.15.0a3__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 (67) hide show
  1. plotnine/_mpl/layout_manager/_layout_tree.py +16 -6
  2. plotnine/_utils/__init__.py +4 -2
  3. plotnine/geoms/annotation_logticks.py +5 -8
  4. plotnine/geoms/annotation_stripes.py +4 -6
  5. plotnine/geoms/geom.py +20 -8
  6. plotnine/geoms/geom_abline.py +3 -2
  7. plotnine/geoms/geom_blank.py +0 -3
  8. plotnine/geoms/geom_boxplot.py +4 -4
  9. plotnine/geoms/geom_crossbar.py +3 -3
  10. plotnine/geoms/geom_dotplot.py +1 -1
  11. plotnine/geoms/geom_errorbar.py +2 -2
  12. plotnine/geoms/geom_errorbarh.py +2 -2
  13. plotnine/geoms/geom_hline.py +3 -2
  14. plotnine/geoms/geom_linerange.py +2 -2
  15. plotnine/geoms/geom_map.py +3 -3
  16. plotnine/geoms/geom_path.py +10 -11
  17. plotnine/geoms/geom_point.py +4 -5
  18. plotnine/geoms/geom_pointrange.py +3 -5
  19. plotnine/geoms/geom_polygon.py +2 -3
  20. plotnine/geoms/geom_raster.py +4 -5
  21. plotnine/geoms/geom_rect.py +3 -4
  22. plotnine/geoms/geom_ribbon.py +7 -7
  23. plotnine/geoms/geom_rug.py +1 -1
  24. plotnine/geoms/geom_segment.py +2 -2
  25. plotnine/geoms/geom_smooth.py +3 -3
  26. plotnine/geoms/geom_step.py +2 -2
  27. plotnine/geoms/geom_text.py +2 -3
  28. plotnine/geoms/geom_violin.py +4 -5
  29. plotnine/geoms/geom_vline.py +3 -2
  30. plotnine/guides/guides.py +1 -1
  31. plotnine/layer.py +18 -12
  32. plotnine/mapping/_eval_environment.py +1 -1
  33. plotnine/scales/scale_color.py +46 -14
  34. plotnine/scales/scale_continuous.py +5 -4
  35. plotnine/scales/scale_datetime.py +28 -14
  36. plotnine/scales/scale_discrete.py +2 -2
  37. plotnine/scales/scale_xy.py +2 -2
  38. plotnine/stats/smoothers.py +19 -19
  39. plotnine/stats/stat.py +15 -25
  40. plotnine/stats/stat_bin.py +2 -5
  41. plotnine/stats/stat_bin_2d.py +7 -9
  42. plotnine/stats/stat_bindot.py +5 -8
  43. plotnine/stats/stat_boxplot.py +5 -5
  44. plotnine/stats/stat_count.py +5 -9
  45. plotnine/stats/stat_density.py +5 -8
  46. plotnine/stats/stat_density_2d.py +12 -9
  47. plotnine/stats/stat_ecdf.py +6 -5
  48. plotnine/stats/stat_ellipse.py +5 -6
  49. plotnine/stats/stat_function.py +6 -8
  50. plotnine/stats/stat_hull.py +2 -3
  51. plotnine/stats/stat_identity.py +1 -2
  52. plotnine/stats/stat_pointdensity.py +4 -7
  53. plotnine/stats/stat_qq.py +45 -20
  54. plotnine/stats/stat_qq_line.py +15 -11
  55. plotnine/stats/stat_quantile.py +6 -7
  56. plotnine/stats/stat_sina.py +12 -14
  57. plotnine/stats/stat_smooth.py +7 -10
  58. plotnine/stats/stat_sum.py +1 -2
  59. plotnine/stats/stat_summary.py +6 -9
  60. plotnine/stats/stat_summary_bin.py +10 -13
  61. plotnine/stats/stat_unique.py +1 -2
  62. plotnine/stats/stat_ydensity.py +7 -10
  63. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a3.dist-info}/METADATA +3 -3
  64. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a3.dist-info}/RECORD +67 -67
  65. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a3.dist-info}/WHEEL +1 -1
  66. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a3.dist-info}/licenses/LICENSE +0 -0
  67. {plotnine-0.15.0a2.dist-info → plotnine-0.15.0a3.dist-info}/top_level.txt +0 -0
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
17
17
  from plotnine.mapping import Environment
18
18
 
19
19
 
20
- def predictdf(data, xseq, **params) -> pd.DataFrame:
20
+ def predictdf(data, xseq, params) -> pd.DataFrame:
21
21
  """
22
22
  Make prediction on the data
23
23
 
@@ -49,21 +49,21 @@ def predictdf(data, xseq, **params) -> pd.DataFrame:
49
49
  if not callable(method):
50
50
  msg = (
51
51
  "'method' should either be a string or a function"
52
- "with the signature `func(data, xseq, **params)`"
52
+ "with the signature `func(data, xseq, params)`"
53
53
  )
54
54
  raise PlotnineError(msg)
55
55
 
56
- return method(data, xseq, **params)
56
+ return method(data, xseq, params)
57
57
 
58
58
 
59
- def lm(data, xseq, **params) -> pd.DataFrame:
59
+ def lm(data, xseq, params) -> pd.DataFrame:
60
60
  """
61
61
  Fit OLS / WLS if data has weight
62
62
  """
63
63
  import statsmodels.api as sm
64
64
 
65
65
  if params["formula"]:
66
- return lm_formula(data, xseq, **params)
66
+ return lm_formula(data, xseq, params)
67
67
 
68
68
  X = sm.add_constant(data["x"])
69
69
  Xseq = sm.add_constant(xseq)
@@ -96,7 +96,7 @@ def lm(data, xseq, **params) -> pd.DataFrame:
96
96
  return data
97
97
 
98
98
 
99
- def lm_formula(data, xseq, **params) -> pd.DataFrame:
99
+ def lm_formula(data, xseq, params) -> pd.DataFrame:
100
100
  """
101
101
  Fit OLS / WLS using a formula
102
102
  """
@@ -140,14 +140,14 @@ def lm_formula(data, xseq, **params) -> pd.DataFrame:
140
140
  return data
141
141
 
142
142
 
143
- def rlm(data, xseq, **params) -> pd.DataFrame:
143
+ def rlm(data, xseq, params) -> pd.DataFrame:
144
144
  """
145
145
  Fit RLM
146
146
  """
147
147
  import statsmodels.api as sm
148
148
 
149
149
  if params["formula"]:
150
- return rlm_formula(data, xseq, **params)
150
+ return rlm_formula(data, xseq, params)
151
151
 
152
152
  X = sm.add_constant(data["x"])
153
153
  Xseq = sm.add_constant(xseq)
@@ -170,7 +170,7 @@ def rlm(data, xseq, **params) -> pd.DataFrame:
170
170
  return data
171
171
 
172
172
 
173
- def rlm_formula(data, xseq, **params) -> pd.DataFrame:
173
+ def rlm_formula(data, xseq, params) -> pd.DataFrame:
174
174
  """
175
175
  Fit RLM using a formula
176
176
  """
@@ -196,14 +196,14 @@ def rlm_formula(data, xseq, **params) -> pd.DataFrame:
196
196
  return data
197
197
 
198
198
 
199
- def gls(data, xseq, **params) -> pd.DataFrame:
199
+ def gls(data, xseq, params) -> pd.DataFrame:
200
200
  """
201
201
  Fit GLS
202
202
  """
203
203
  import statsmodels.api as sm
204
204
 
205
205
  if params["formula"]:
206
- return gls_formula(data, xseq, **params)
206
+ return gls_formula(data, xseq, params)
207
207
 
208
208
  X = sm.add_constant(data["x"])
209
209
  Xseq = sm.add_constant(xseq)
@@ -227,7 +227,7 @@ def gls(data, xseq, **params) -> pd.DataFrame:
227
227
  return data
228
228
 
229
229
 
230
- def gls_formula(data, xseq, **params):
230
+ def gls_formula(data, xseq, params):
231
231
  """
232
232
  Fit GLL using a formula
233
233
  """
@@ -258,14 +258,14 @@ def gls_formula(data, xseq, **params):
258
258
  return data
259
259
 
260
260
 
261
- def glm(data, xseq, **params) -> pd.DataFrame:
261
+ def glm(data, xseq, params) -> pd.DataFrame:
262
262
  """
263
263
  Fit GLM
264
264
  """
265
265
  import statsmodels.api as sm
266
266
 
267
267
  if params["formula"]:
268
- return glm_formula(data, xseq, **params)
268
+ return glm_formula(data, xseq, params)
269
269
 
270
270
  X = sm.add_constant(data["x"])
271
271
  Xseq = sm.add_constant(xseq)
@@ -292,7 +292,7 @@ def glm(data, xseq, **params) -> pd.DataFrame:
292
292
  return data
293
293
 
294
294
 
295
- def glm_formula(data, xseq, **params):
295
+ def glm_formula(data, xseq, params):
296
296
  """
297
297
  Fit with GLM formula
298
298
  """
@@ -321,7 +321,7 @@ def glm_formula(data, xseq, **params):
321
321
  return data
322
322
 
323
323
 
324
- def lowess(data, xseq, **params) -> pd.DataFrame:
324
+ def lowess(data, xseq, params) -> pd.DataFrame:
325
325
  """
326
326
  Lowess fitting
327
327
  """
@@ -351,7 +351,7 @@ def lowess(data, xseq, **params) -> pd.DataFrame:
351
351
  return data
352
352
 
353
353
 
354
- def loess(data, xseq, **params) -> pd.DataFrame:
354
+ def loess(data, xseq, params) -> pd.DataFrame:
355
355
  """
356
356
  Loess smoothing
357
357
  """
@@ -402,7 +402,7 @@ def loess(data, xseq, **params) -> pd.DataFrame:
402
402
  return data
403
403
 
404
404
 
405
- def mavg(data, xseq, **params) -> pd.DataFrame:
405
+ def mavg(data, xseq, params) -> pd.DataFrame:
406
406
  """
407
407
  Fit moving average
408
408
  """
@@ -426,7 +426,7 @@ def mavg(data, xseq, **params) -> pd.DataFrame:
426
426
  return data
427
427
 
428
428
 
429
- def gpr(data, xseq, **params):
429
+ def gpr(data, xseq, params):
430
430
  """
431
431
  Fit gaussian process
432
432
  """
plotnine/stats/stat.py CHANGED
@@ -195,9 +195,9 @@ class stat(ABC, metaclass=Register):
195
195
 
196
196
  return data
197
197
 
198
- def setup_params(self, data: pd.DataFrame) -> dict[str, Any]:
198
+ def setup_params(self, data: pd.DataFrame):
199
199
  """
200
- Override this to verify or adjust parameters
200
+ Override this to verify and/or adjust parameters
201
201
 
202
202
  Parameters
203
203
  ----------
@@ -209,7 +209,6 @@ class stat(ABC, metaclass=Register):
209
209
  out :
210
210
  Parameters used by the stats.
211
211
  """
212
- return self.params
213
212
 
214
213
  def setup_data(self, data: pd.DataFrame) -> pd.DataFrame:
215
214
  """
@@ -227,9 +226,7 @@ class stat(ABC, metaclass=Register):
227
226
  """
228
227
  return data
229
228
 
230
- def finish_layer(
231
- self, data: pd.DataFrame, params: dict[str, Any]
232
- ) -> pd.DataFrame:
229
+ def finish_layer(self, data: pd.DataFrame) -> pd.DataFrame:
233
230
  """
234
231
  Modify data after the aesthetics have been mapped
235
232
 
@@ -257,9 +254,8 @@ class stat(ABC, metaclass=Register):
257
254
  """
258
255
  return data
259
256
 
260
- @classmethod
261
257
  def compute_layer(
262
- cls, data: pd.DataFrame, params: dict[str, Any], layout: Layout
258
+ self, data: pd.DataFrame, layout: Layout
263
259
  ) -> pd.DataFrame:
264
260
  """
265
261
  Calculate statistics for this layers
@@ -275,22 +271,20 @@ class stat(ABC, metaclass=Register):
275
271
  ----------
276
272
  data :
277
273
  Data points for all objects in a layer.
278
- params :
279
- Stat parameters
280
274
  layout :
281
275
  Panel layout information
282
276
  """
283
277
  check_required_aesthetics(
284
- cls.REQUIRED_AES,
285
- list(data.columns) + list(params.keys()),
286
- cls.__name__,
278
+ self.REQUIRED_AES,
279
+ list(data.columns) + list(self.params.keys()),
280
+ self.__class__.__name__,
287
281
  )
288
282
 
289
283
  data = remove_missing(
290
284
  data,
291
- na_rm=params.get("na_rm", False),
292
- vars=list(cls.REQUIRED_AES | cls.NON_MISSING_AES),
293
- name=cls.__name__,
285
+ na_rm=self.params.get("na_rm", False),
286
+ vars=list(self.REQUIRED_AES | self.NON_MISSING_AES),
287
+ name=self.__class__.__name__,
294
288
  finite=True,
295
289
  )
296
290
 
@@ -304,14 +298,11 @@ class stat(ABC, metaclass=Register):
304
298
  if len(pdata) == 0:
305
299
  return pdata
306
300
  pscales = layout.get_scales(pdata["PANEL"].iloc[0])
307
- return cls.compute_panel(pdata, pscales, **params)
301
+ return self.compute_panel(pdata, pscales)
308
302
 
309
303
  return groupby_apply(data, "PANEL", fn)
310
304
 
311
- @classmethod
312
- def compute_panel(
313
- cls, data: pd.DataFrame, scales: pos_scales, **params: Any
314
- ):
305
+ def compute_panel(self, data: pd.DataFrame, scales: pos_scales):
315
306
  """
316
307
  Calculate the statistics for all the groups
317
308
 
@@ -341,7 +332,7 @@ class stat(ABC, metaclass=Register):
341
332
 
342
333
  stats = []
343
334
  for _, old in data.groupby("group"):
344
- new = cls.compute_group(old, scales, **params)
335
+ new = self.compute_group(old, scales)
345
336
  new.reset_index(drop=True, inplace=True)
346
337
  unique = uniquecols(old)
347
338
  missing = unique.columns.difference(new.columns)
@@ -365,9 +356,8 @@ class stat(ABC, metaclass=Register):
365
356
  # it completely.
366
357
  return stats
367
358
 
368
- @classmethod
369
359
  def compute_group(
370
- cls, data: pd.DataFrame, scales: pos_scales, **params: Any
360
+ self, data: pd.DataFrame, scales: pos_scales
371
361
  ) -> pd.DataFrame:
372
362
  """
373
363
  Calculate statistics for the group
@@ -390,7 +380,7 @@ class stat(ABC, metaclass=Register):
390
380
  Parameters
391
381
  """
392
382
  msg = "{} should implement this method."
393
- raise NotImplementedError(msg.format(cls.__name__))
383
+ raise NotImplementedError(msg.format(self.__class__.__name__))
394
384
 
395
385
  def __radd__(self, other: ggplot) -> ggplot:
396
386
  """
@@ -100,7 +100,6 @@ class stat_bin(stat):
100
100
  and params["binwidth"] is None
101
101
  and params["bins"] is None
102
102
  ):
103
- params = params.copy()
104
103
  params["bins"] = freedman_diaconis_bins(data["x"])
105
104
  msg = (
106
105
  "'stat_bin()' using 'bins = {}'. "
@@ -108,10 +107,8 @@ class stat_bin(stat):
108
107
  )
109
108
  warn(msg.format(params["bins"]), PlotnineWarning)
110
109
 
111
- return params
112
-
113
- @classmethod
114
- def compute_group(cls, data, scales, **params):
110
+ def compute_group(self, data, scales):
111
+ params = self.params
115
112
  if params["breaks"] is not None:
116
113
  breaks = np.asarray(params["breaks"])
117
114
  if hasattr(scales.x, "transform"):
@@ -66,18 +66,16 @@ class stat_bin_2d(stat):
66
66
  CREATES = {"xmin", "xmax", "ymin", "ymax", "count", "density"}
67
67
 
68
68
  def setup_params(self, data):
69
- params = self.params.copy()
69
+ params = self.params
70
70
  params["bins"] = dual_param(params["bins"])
71
71
  params["breaks"] = dual_param(params["breaks"])
72
72
  params["binwidth"] = dual_param(params["binwidth"])
73
- return params
74
-
75
- @classmethod
76
- def compute_group(cls, data, scales, **params):
77
- bins = params["bins"]
78
- breaks = params["breaks"]
79
- binwidth = params["binwidth"]
80
- drop = params["drop"]
73
+
74
+ def compute_group(self, data, scales):
75
+ bins = self.params["bins"]
76
+ breaks = self.params["breaks"]
77
+ binwidth = self.params["binwidth"]
78
+ drop = self.params["drop"]
81
79
  weight = data.get("weight")
82
80
 
83
81
  if weight is None:
@@ -113,7 +113,6 @@ class stat_bindot(stat):
113
113
  and params["binwidth"] is None
114
114
  and params["bins"] is None
115
115
  ):
116
- params = params.copy()
117
116
  params["bins"] = freedman_diaconis_bins(data["x"])
118
117
  msg = (
119
118
  "'stat_bin()' using 'bins = {}'. "
@@ -121,10 +120,8 @@ class stat_bindot(stat):
121
120
  )
122
121
  warn(msg.format(params["bins"]), PlotnineWarning)
123
122
 
124
- return params
125
-
126
- @classmethod
127
- def compute_panel(cls, data, scales, **params):
123
+ def compute_panel(self, data, scales):
124
+ params = self.params
128
125
  if (
129
126
  params["method"] == "dotdensity"
130
127
  and params["binpositions"] == "all"
@@ -160,10 +157,10 @@ class stat_bindot(stat):
160
157
  data["binwidth"] = newdata["binwidth"]
161
158
  data["weight"] = newdata["weight"]
162
159
  data["bincenter"] = newdata["bincenter"]
163
- return super(cls, stat_bindot).compute_panel(data, scales, **params)
160
+ return super().compute_panel(data, scales)
164
161
 
165
- @classmethod
166
- def compute_group(cls, data, scales, **params):
162
+ def compute_group(self, data, scales):
163
+ params = self.params
167
164
  # Check that weights are whole numbers
168
165
  # (for dots, weights must be whole)
169
166
  weight = data.get("weight")
@@ -91,10 +91,8 @@ class stat_boxplot(stat):
91
91
  if self.params["width"] is None:
92
92
  x = data.get("x", 0)
93
93
  self.params["width"] = resolution(x, False) * 0.75
94
- return self.params
95
94
 
96
- @classmethod
97
- def compute_group(cls, data, scales, **params):
95
+ def compute_group(self, data, scales):
98
96
  n = len(data)
99
97
  y = data["y"].to_numpy()
100
98
  if "weight" in data:
@@ -103,12 +101,14 @@ class stat_boxplot(stat):
103
101
  else:
104
102
  weights = None
105
103
  total_weight = len(y)
106
- res = weighted_boxplot_stats(y, weights=weights, whis=params["coef"])
104
+ res = weighted_boxplot_stats(
105
+ y, weights=weights, whis=self.params["coef"]
106
+ )
107
107
 
108
108
  if len(np.unique(data["x"])) > 1:
109
109
  width = np.ptp(data["x"]) * 0.9
110
110
  else:
111
- width = params["width"]
111
+ width = self.params["width"]
112
112
 
113
113
  if isinstance(data["x"].dtype, pd.CategoricalDtype):
114
114
  x = data["x"].iloc[0]
@@ -49,21 +49,17 @@ class stat_count(stat):
49
49
  CREATES = {"count", "prop"}
50
50
 
51
51
  def setup_params(self, data):
52
- params = self.params.copy()
53
- if params["width"] is None:
54
- params["width"] = resolution(data["x"], False) * 0.9
52
+ if self.params["width"] is None:
53
+ self.params["width"] = resolution(data["x"], False) * 0.9
55
54
 
56
- return params
57
-
58
- @classmethod
59
- def compute_group(cls, data, scales, **params):
55
+ def compute_group(self, data, scales):
60
56
  x = data["x"]
61
- if ("y" in data) or ("y" in params):
57
+ if ("y" in data) or ("y" in self.params):
62
58
  msg = "stat_count() must not be used with a y aesthetic"
63
59
  raise PlotnineError(msg)
64
60
 
65
61
  weight = data.get("weight", [1] * len(x))
66
- width = params["width"]
62
+ width = self.params["width"]
67
63
  xdata_long = pd.DataFrame({"x": x, "weight": weight})
68
64
  # weighted frequency count
69
65
  count = xdata_long.pivot_table("weight", index=["x"], aggfunc="sum")[
@@ -126,7 +126,7 @@ class stat_density(stat):
126
126
  CREATES = {"density", "count", "scaled", "n"}
127
127
 
128
128
  def setup_params(self, data):
129
- params = self.params.copy()
129
+ params = self.params
130
130
  lookup = {
131
131
  "biweight": "biw",
132
132
  "cosine": "cos",
@@ -148,21 +148,18 @@ class stat_density(stat):
148
148
  )
149
149
  raise PlotnineError(msg)
150
150
 
151
- return params
152
-
153
- @classmethod
154
- def compute_group(cls, data, scales, **params):
151
+ def compute_group(self, data, scales):
155
152
  weight = data.get("weight")
156
153
 
157
- if params["trim"]:
154
+ if self.params["trim"]:
158
155
  range_x = data["x"].min(), data["x"].max()
159
156
  else:
160
157
  range_x = scales.x.dimension()
161
158
 
162
- return compute_density(data["x"], weight, range_x, **params)
159
+ return compute_density(data["x"], weight, range_x, self.params)
163
160
 
164
161
 
165
- def compute_density(x, weight, range, **params):
162
+ def compute_density(x, weight, range, params):
166
163
  """
167
164
  Compute density
168
165
  """
@@ -1,12 +1,17 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
1
5
  import numpy as np
2
6
  import pandas as pd
3
7
 
4
- from ..doctools import document
5
8
  from .density import get_var_type, kde
6
9
  from .stat import stat
7
10
 
11
+ if TYPE_CHECKING:
12
+ from plotnine.typing import FloatArrayLike
13
+
8
14
 
9
- @document
10
15
  class stat_density_2d(stat):
11
16
  """
12
17
  Compute 2D kernel density estimation
@@ -66,7 +71,7 @@ class stat_density_2d(stat):
66
71
  CREATES = {"y"}
67
72
 
68
73
  def setup_params(self, data):
69
- params = self.params.copy()
74
+ params = self.params
70
75
  if params["kde_params"] is None:
71
76
  params["kde_params"] = {}
72
77
 
@@ -78,10 +83,8 @@ class stat_density_2d(stat):
78
83
  y_type = get_var_type(data["y"])
79
84
  kde_params["var_type"] = f"{x_type}{y_type}"
80
85
 
81
- return params
82
-
83
- @classmethod
84
- def compute_group(cls, data, scales, **params):
86
+ def compute_group(self, data, scales):
87
+ params = self.params
85
88
  package = params["package"]
86
89
  kde_params = params["kde_params"]
87
90
 
@@ -118,7 +121,7 @@ class stat_density_2d(stat):
118
121
  return data
119
122
 
120
123
 
121
- def contour_lines(X, Y, Z, levels):
124
+ def contour_lines(X, Y, Z, levels: int | FloatArrayLike):
122
125
  """
123
126
  Calculate contour lines
124
127
  """
@@ -152,7 +155,7 @@ def contour_lines(X, Y, Z, levels):
152
155
  level_values = []
153
156
  start_pid = 1
154
157
  for level in levels:
155
- vertices, *_ = cgen.create_contour(level)
158
+ vertices, *_ = cgen.create_contour(level) # pyright: ignore[reportArgumentType]
156
159
  for pid, piece in enumerate(vertices, start=start_pid):
157
160
  n = len(piece) # pyright: ignore
158
161
  segments.append(piece)
@@ -50,17 +50,18 @@ class stat_ecdf(stat):
50
50
  DEFAULT_AES = {"y": after_stat("ecdf")}
51
51
  CREATES = {"ecdf"}
52
52
 
53
- @classmethod
54
- def compute_group(cls, data, scales, **params):
53
+ def compute_group(self, data, scales):
55
54
  from statsmodels.distributions.empirical_distribution import ECDF
56
55
 
56
+ n, pad = self.params["n"], self.params["pad"]
57
+
57
58
  # If n is None, use raw values; otherwise interpolate
58
- if params["n"] is None:
59
+ if n is None:
59
60
  x = np.unique(data["x"])
60
61
  else:
61
- x = np.linspace(data["x"].min(), data["x"].max(), params["n"])
62
+ x = np.linspace(data["x"].min(), data["x"].max(), n)
62
63
 
63
- if params["pad"]:
64
+ if pad:
64
65
  x = np.hstack([-np.inf, x, np.inf])
65
66
 
66
67
  ecdf = ECDF(data["x"].to_numpy())(x)
@@ -49,14 +49,13 @@ class stat_ellipse(stat):
49
49
  "segments": 51,
50
50
  }
51
51
 
52
- @classmethod
53
- def compute_group(cls, data, scales, **params):
52
+ def compute_group(self, data, scales):
54
53
  import scipy.stats as stats
55
54
  from scipy import linalg
56
55
 
57
- level = params["level"]
58
- segments = params["segments"]
59
- type_ = params["type"]
56
+ level = self.params["level"]
57
+ segments = self.params["segments"]
58
+ type_ = self.params["type"]
60
59
 
61
60
  dfn = 2
62
61
  dfd = len(data) - 1
@@ -203,7 +202,7 @@ def cov_trob(
203
202
  wt = wt[wt > 0]
204
203
  n, _ = x.shape
205
204
 
206
- wt = wt[:, np.newaxis]
205
+ wt = wt[:, np.newaxis] # pyright: ignore[reportCallIssue,reportArgumentType,reportOptionalSubscript]
207
206
 
208
207
  # loc
209
208
  use_loc = False
@@ -82,14 +82,12 @@ class stat_function(stat):
82
82
  "stat_function requires parameter 'fun' to be "
83
83
  "a function or any other callable object"
84
84
  )
85
- return self.params
86
-
87
- @classmethod
88
- def compute_group(cls, data, scales, **params):
89
- old_fun: Callable[..., FloatArrayLike] = params["fun"]
90
- n = params["n"]
91
- args = params["args"]
92
- xlim = params["xlim"]
85
+
86
+ def compute_group(self, data, scales):
87
+ old_fun: Callable[..., FloatArrayLike] = self.params["fun"]
88
+ n = self.params["n"]
89
+ args = self.params["args"]
90
+ xlim = self.params["xlim"]
93
91
  range_x = xlim or scales.x.dimension((0, 0))
94
92
 
95
93
  if isinstance(args, (list, tuple)):
@@ -47,12 +47,11 @@ class stat_hull(stat):
47
47
  }
48
48
  CREATES = {"area"}
49
49
 
50
- @classmethod
51
- def compute_group(cls, data, scales, **params):
50
+ def compute_group(self, data, scales):
52
51
  from scipy.spatial import ConvexHull
53
52
 
54
53
  hull = ConvexHull(
55
- data[["x", "y"]], qhull_options=params["qhull_options"]
54
+ data[["x", "y"]], qhull_options=self.params["qhull_options"]
56
55
  )
57
56
  idx = np.hstack([hull.vertices, hull.vertices[0]])
58
57
 
@@ -16,6 +16,5 @@ class stat_identity(stat):
16
16
 
17
17
  DEFAULT_PARAMS = {"geom": "point", "position": "identity", "na_rm": False}
18
18
 
19
- @classmethod
20
- def compute_panel(cls, data, scales, **params):
19
+ def compute_panel(self, data, scales):
21
20
  return data
@@ -51,7 +51,7 @@ class stat_pointdensity(stat):
51
51
  CREATES = {"density"}
52
52
 
53
53
  def setup_params(self, data):
54
- params = self.params.copy()
54
+ params = self.params
55
55
  if params["kde_params"] is None:
56
56
  params["kde_params"] = {}
57
57
 
@@ -63,12 +63,9 @@ class stat_pointdensity(stat):
63
63
  y_type = get_var_type(data["y"])
64
64
  kde_params["var_type"] = f"{x_type}{y_type}"
65
65
 
66
- return params
67
-
68
- @classmethod
69
- def compute_group(cls, data, scales, **params):
70
- package = params["package"]
71
- kde_params = params["kde_params"]
66
+ def compute_group(self, data, scales):
67
+ package = self.params["package"]
68
+ kde_params = self.params["kde_params"]
72
69
 
73
70
  var_data = np.array([data["x"].to_numpy(), data["y"].to_numpy()]).T
74
71
  density = kde(var_data, var_data, package, **kde_params)