ggplot2-python 4.0.2.9000__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 (54) hide show
  1. ggplot2_py/__init__.py +852 -0
  2. ggplot2_py/_compat.py +475 -0
  3. ggplot2_py/_plugins.py +129 -0
  4. ggplot2_py/_utils.py +544 -0
  5. ggplot2_py/aes.py +586 -0
  6. ggplot2_py/annotation.py +540 -0
  7. ggplot2_py/coord.py +2108 -0
  8. ggplot2_py/coords/__init__.py +49 -0
  9. ggplot2_py/datasets.py +265 -0
  10. ggplot2_py/draw_key.py +454 -0
  11. ggplot2_py/facet.py +1456 -0
  12. ggplot2_py/fortify.py +95 -0
  13. ggplot2_py/geom.py +4516 -0
  14. ggplot2_py/geoms/__init__.py +12 -0
  15. ggplot2_py/ggproto.py +279 -0
  16. ggplot2_py/guide.py +2925 -0
  17. ggplot2_py/guide_axis.py +615 -0
  18. ggplot2_py/guide_colourbar.py +657 -0
  19. ggplot2_py/guide_legend.py +1061 -0
  20. ggplot2_py/guides/__init__.py +8 -0
  21. ggplot2_py/labeller.py +296 -0
  22. ggplot2_py/labels.py +309 -0
  23. ggplot2_py/layer.py +954 -0
  24. ggplot2_py/layout.py +754 -0
  25. ggplot2_py/limits.py +314 -0
  26. ggplot2_py/plot.py +1401 -0
  27. ggplot2_py/plot_render.py +866 -0
  28. ggplot2_py/position.py +1269 -0
  29. ggplot2_py/protocols.py +171 -0
  30. ggplot2_py/py.typed +0 -0
  31. ggplot2_py/qplot.py +233 -0
  32. ggplot2_py/resources/diamonds.csv +53941 -0
  33. ggplot2_py/resources/economics.csv +575 -0
  34. ggplot2_py/resources/economics_long.csv +2871 -0
  35. ggplot2_py/resources/faithfuld.csv +5626 -0
  36. ggplot2_py/resources/luv_colours.csv +658 -0
  37. ggplot2_py/resources/midwest.csv +438 -0
  38. ggplot2_py/resources/mpg.csv +235 -0
  39. ggplot2_py/resources/msleep.csv +84 -0
  40. ggplot2_py/resources/presidential.csv +13 -0
  41. ggplot2_py/resources/seals.csv +1156 -0
  42. ggplot2_py/resources/txhousing.csv +8603 -0
  43. ggplot2_py/save.py +316 -0
  44. ggplot2_py/scale.py +2727 -0
  45. ggplot2_py/scales/__init__.py +4252 -0
  46. ggplot2_py/stat.py +6071 -0
  47. ggplot2_py/stats/__init__.py +9 -0
  48. ggplot2_py/theme.py +490 -0
  49. ggplot2_py/theme_defaults.py +1350 -0
  50. ggplot2_py/theme_elements.py +2052 -0
  51. ggplot2_python-4.0.2.9000.dist-info/METADATA +179 -0
  52. ggplot2_python-4.0.2.9000.dist-info/RECORD +54 -0
  53. ggplot2_python-4.0.2.9000.dist-info/WHEEL +4 -0
  54. ggplot2_python-4.0.2.9000.dist-info/licenses/LICENSE +3 -0
ggplot2_py/draw_key.py ADDED
@@ -0,0 +1,454 @@
1
+ """
2
+ Legend key drawing functions for ggplot2.
3
+
4
+ Each ``draw_key_*`` function draws a single legend glyph for a given geom.
5
+ They accept the same three arguments: *data* (a single-row dict-like of
6
+ scaled aesthetics), *params* (extra layer parameters), and *size* (key
7
+ dimensions in mm).
8
+
9
+ Notes
10
+ -----
11
+ All functions return a grid_py grob.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from typing import Any, Dict, Optional, Union
17
+
18
+ import numpy as np
19
+
20
+ from grid_py import (
21
+ points_grob,
22
+ rect_grob,
23
+ segments_grob,
24
+ lines_grob,
25
+ polygon_grob,
26
+ text_grob,
27
+ circle_grob,
28
+ null_grob,
29
+ Gpar,
30
+ Unit,
31
+ grob_tree,
32
+ GTree,
33
+ Viewport,
34
+ roundrect_grob,
35
+ GList,
36
+ )
37
+
38
+ from scales import alpha as _scales_alpha
39
+
40
+ __all__ = [
41
+ "draw_key_point",
42
+ "draw_key_path",
43
+ "draw_key_rect",
44
+ "draw_key_polygon",
45
+ "draw_key_blank",
46
+ "draw_key_boxplot",
47
+ "draw_key_crossbar",
48
+ "draw_key_dotplot",
49
+ "draw_key_label",
50
+ "draw_key_linerange",
51
+ "draw_key_pointrange",
52
+ "draw_key_smooth",
53
+ "draw_key_text",
54
+ "draw_key_abline",
55
+ "draw_key_vline",
56
+ "draw_key_timeseries",
57
+ "draw_key_vpath",
58
+ ]
59
+
60
+ # ---------------------------------------------------------------------------
61
+ # Graphic-unit constants (same as R's ggplot2)
62
+ # ---------------------------------------------------------------------------
63
+
64
+ _PT: float = 72.27 / 25.4
65
+ _STROKE: float = 96 / 25.4
66
+
67
+
68
+ def _alpha(colour: Any, alpha_val: Any) -> Any:
69
+ """Apply alpha to a colour, tolerating ``None``/``np.nan``."""
70
+ try:
71
+ return _scales_alpha(colour, alpha_val)
72
+ except Exception:
73
+ return colour
74
+
75
+
76
+ def _fill_alpha(fill: Any, alpha_val: Any) -> Any:
77
+ """Like ``fill_alpha`` in R -- apply alpha only for non-NA fills."""
78
+ if fill is None:
79
+ return None
80
+ try:
81
+ return _scales_alpha(fill, alpha_val)
82
+ except Exception:
83
+ return fill
84
+
85
+
86
+ def _get(data: Any, key: str, default: Any = None) -> Any:
87
+ """Safely get a value from a dict-like *data*."""
88
+ if isinstance(data, dict):
89
+ return data.get(key, default)
90
+ return getattr(data, key, default)
91
+
92
+
93
+ # ---------------------------------------------------------------------------
94
+ # Key glyph functions
95
+ # ---------------------------------------------------------------------------
96
+
97
+
98
+ def draw_key_point(
99
+ data: Dict[str, Any],
100
+ params: Dict[str, Any],
101
+ size: Any = None,
102
+ ) -> Any:
103
+ """Draw a legend key for point geoms.
104
+
105
+ Parameters
106
+ ----------
107
+ data : dict
108
+ Scaled aesthetics for a single legend entry.
109
+ params : dict
110
+ Extra layer parameters.
111
+ size : optional
112
+ Key dimensions.
113
+
114
+ Returns
115
+ -------
116
+ grob
117
+ A grid_py ``points_grob``.
118
+ """
119
+ shape = _get(data, "shape", 19)
120
+ from ggplot2_py.geom import translate_shape_string
121
+ shape = translate_shape_string(shape)
122
+
123
+ return points_grob(
124
+ x=0.5,
125
+ y=0.5,
126
+ pch=shape,
127
+ gp=Gpar(
128
+ col=_alpha(_get(data, "colour", "black"), _get(data, "alpha")),
129
+ fill=_fill_alpha(_get(data, "fill", "black"), _get(data, "alpha")),
130
+ fontsize=(_get(data, "size", 1.5) * _PT) + (_get(data, "stroke", 0.5) * _STROKE),
131
+ lwd=_get(data, "stroke", 0.5) * _STROKE,
132
+ ),
133
+ )
134
+
135
+
136
+ def draw_key_abline(
137
+ data: Dict[str, Any],
138
+ params: Dict[str, Any],
139
+ size: Any = None,
140
+ ) -> Any:
141
+ """Draw a legend key for abline geoms (diagonal segment)."""
142
+ return segments_grob(
143
+ x0=0, y0=0, x1=1, y1=1,
144
+ gp=Gpar(
145
+ col=_alpha(
146
+ _get(data, "colour", _get(data, "fill", "black")),
147
+ _get(data, "alpha"),
148
+ ),
149
+ lwd=_get(data, "linewidth", 0.5) * _PT,
150
+ lty=_get(data, "linetype", 1),
151
+ lineend=_get(params, "lineend", "butt"),
152
+ ),
153
+ )
154
+
155
+
156
+ def draw_key_rect(
157
+ data: Dict[str, Any],
158
+ params: Dict[str, Any],
159
+ size: Any = None,
160
+ ) -> Any:
161
+ """Draw a legend key for rect/tile geoms (filled rectangle)."""
162
+ fill = _get(data, "fill")
163
+ colour = fill if fill is not None else _get(data, "colour")
164
+ return rect_grob(
165
+ gp=Gpar(
166
+ col=None,
167
+ fill=_fill_alpha(colour if colour is not None else "grey20", _get(data, "alpha")),
168
+ lty=_get(data, "linetype", 1),
169
+ ),
170
+ )
171
+
172
+
173
+ def draw_key_polygon(
174
+ data: Dict[str, Any],
175
+ params: Dict[str, Any],
176
+ size: Any = None,
177
+ ) -> Any:
178
+ """Draw a legend key for polygon/bar geoms (outlined filled rectangle)."""
179
+ lwd = _get(data, "linewidth", 0)
180
+ return rect_grob(
181
+ gp=Gpar(
182
+ col=_get(data, "colour"),
183
+ fill=_fill_alpha(_get(data, "fill", "grey20"), _get(data, "alpha")),
184
+ lty=_get(data, "linetype", 1),
185
+ lwd=lwd * _PT if lwd else 0,
186
+ linejoin=_get(params, "linejoin", "mitre"),
187
+ lineend=_get(params, "lineend", "butt"),
188
+ ),
189
+ )
190
+
191
+
192
+ def draw_key_blank(
193
+ data: Dict[str, Any],
194
+ params: Dict[str, Any],
195
+ size: Any = None,
196
+ ) -> Any:
197
+ """Draw nothing (blank legend key)."""
198
+ return null_grob()
199
+
200
+
201
+ def draw_key_boxplot(
202
+ data: Dict[str, Any],
203
+ params: Dict[str, Any],
204
+ size: Any = None,
205
+ ) -> Any:
206
+ """Draw a legend key for boxplot geoms."""
207
+ gp = Gpar(
208
+ col=_get(data, "colour", "grey20"),
209
+ fill=_fill_alpha(_get(data, "fill", "white"), _get(data, "alpha")),
210
+ lwd=(_get(data, "linewidth", 0.5)) * _PT,
211
+ lty=_get(data, "linetype", 1),
212
+ lineend=_get(params, "lineend", "butt"),
213
+ linejoin=_get(params, "linejoin", "mitre"),
214
+ )
215
+ return grob_tree(
216
+ lines_grob(x=[0.5, 0.5], y=[0.1, 0.25], gp=gp),
217
+ lines_grob(x=[0.5, 0.5], y=[0.75, 0.9], gp=gp),
218
+ rect_grob(height=Unit(0.5, "npc"), width=Unit(0.75, "npc"), gp=gp),
219
+ segments_grob(x0=0.125, y0=0.5, x1=0.875, y1=0.5, gp=gp),
220
+ )
221
+
222
+
223
+ def draw_key_crossbar(
224
+ data: Dict[str, Any],
225
+ params: Dict[str, Any],
226
+ size: Any = None,
227
+ ) -> Any:
228
+ """Draw a legend key for crossbar geoms."""
229
+ gp = Gpar(
230
+ col=_get(data, "colour", "grey20"),
231
+ fill=_fill_alpha(_get(data, "fill", "white"), _get(data, "alpha")),
232
+ lwd=(_get(data, "linewidth", 0.5)) * _PT,
233
+ lty=_get(data, "linetype", 1),
234
+ lineend=_get(params, "lineend", "butt"),
235
+ linejoin=_get(params, "linejoin", "mitre"),
236
+ )
237
+ return grob_tree(
238
+ rect_grob(height=Unit(0.5, "npc"), width=Unit(0.75, "npc"), gp=gp),
239
+ segments_grob(x0=0.125, y0=0.5, x1=0.875, y1=0.5, gp=gp),
240
+ )
241
+
242
+
243
+ def draw_key_dotplot(
244
+ data: Dict[str, Any],
245
+ params: Dict[str, Any],
246
+ size: Any = None,
247
+ ) -> Any:
248
+ """Draw a legend key for dotplot geoms."""
249
+ return points_grob(
250
+ x=0.5,
251
+ y=0.5,
252
+ pch=21,
253
+ size=Unit(0.5, "npc"),
254
+ gp=Gpar(
255
+ col=_alpha(_get(data, "colour", "black"), _get(data, "alpha")),
256
+ fill=_fill_alpha(_get(data, "fill", "black"), _get(data, "alpha")),
257
+ lty=_get(data, "linetype", 1),
258
+ ),
259
+ )
260
+
261
+
262
+ def draw_key_label(
263
+ data: Dict[str, Any],
264
+ params: Dict[str, Any],
265
+ size: Any = None,
266
+ ) -> Any:
267
+ """Draw a legend key for label geoms (text with background)."""
268
+ label = _get(data, "label", "a")
269
+ lwd = _get(data, "linewidth", 0.25)
270
+ return grob_tree(
271
+ roundrect_grob(
272
+ gp=Gpar(
273
+ col=_get(data, "colour", "black") if lwd > 0 else None,
274
+ fill=_fill_alpha(_get(data, "fill", "white"), _get(data, "alpha")),
275
+ lwd=lwd * _PT,
276
+ lty=_get(data, "linetype", 1),
277
+ ),
278
+ ),
279
+ text_grob(
280
+ label=label,
281
+ x=0.5,
282
+ y=0.5,
283
+ gp=Gpar(
284
+ col=_alpha(_get(data, "colour", "black"), _get(data, "alpha")),
285
+ fontsize=(_get(data, "size", 3.88)) * _PT,
286
+ fontfamily=_get(data, "family", ""),
287
+ fontface=_get(data, "fontface", 1),
288
+ ),
289
+ ),
290
+ )
291
+
292
+
293
+ def draw_key_linerange(
294
+ data: Dict[str, Any],
295
+ params: Dict[str, Any],
296
+ size: Any = None,
297
+ ) -> Any:
298
+ """Draw a legend key for linerange geoms (vertical segment)."""
299
+ if _get(params, "flipped_aes", False):
300
+ return draw_key_path(data, params, size)
301
+ return draw_key_vpath(data, params, size)
302
+
303
+
304
+ def draw_key_pointrange(
305
+ data: Dict[str, Any],
306
+ params: Dict[str, Any],
307
+ size: Any = None,
308
+ ) -> Any:
309
+ """Draw a legend key for pointrange geoms."""
310
+ line_grob = draw_key_linerange(data, params, size)
311
+ pt_data = dict(data) if isinstance(data, dict) else {k: getattr(data, k, None) for k in dir(data)}
312
+ pt_data["size"] = (_get(data, "size", 1.5)) * 4
313
+ point_grob = draw_key_point(pt_data, params, size)
314
+ return grob_tree(line_grob, point_grob)
315
+
316
+
317
+ def draw_key_smooth(
318
+ data: Dict[str, Any],
319
+ params: Dict[str, Any],
320
+ size: Any = None,
321
+ ) -> Any:
322
+ """Draw a legend key for smooth geoms (ribbon + line)."""
323
+ fill_colour = _fill_alpha(
324
+ _get(data, "fill", "grey60"),
325
+ _get(data, "alpha"),
326
+ )
327
+ path_grob = draw_key_path(data, params, size)
328
+ se = _get(params, "se", False)
329
+ children = []
330
+ if se:
331
+ children.append(rect_grob(gp=Gpar(col=None, fill=fill_colour)))
332
+ children.append(path_grob)
333
+ return grob_tree(*children)
334
+
335
+
336
+ def draw_key_text(
337
+ data: Dict[str, Any],
338
+ params: Dict[str, Any],
339
+ size: Any = None,
340
+ ) -> Any:
341
+ """Draw a legend key for text geoms."""
342
+ label = _get(data, "label", "a")
343
+ return text_grob(
344
+ label=label,
345
+ x=0.5,
346
+ y=0.5,
347
+ rot=_get(data, "angle", 0),
348
+ gp=Gpar(
349
+ col=_alpha(
350
+ _get(data, "colour", _get(data, "fill", "black")),
351
+ _get(data, "alpha"),
352
+ ),
353
+ fontfamily=_get(data, "family", ""),
354
+ fontface=_get(data, "fontface", 1),
355
+ fontsize=(_get(data, "size", 3.88)) * _PT,
356
+ ),
357
+ )
358
+
359
+
360
+ def draw_key_path(
361
+ data: Dict[str, Any],
362
+ params: Dict[str, Any],
363
+ size: Any = None,
364
+ ) -> Any:
365
+ """Draw a legend key for path/line geoms (horizontal segment)."""
366
+ linetype = _get(data, "linetype")
367
+ if linetype is None:
368
+ linetype = 0
369
+ return segments_grob(
370
+ x0=0.1,
371
+ y0=0.5,
372
+ x1=0.9,
373
+ y1=0.5,
374
+ gp=Gpar(
375
+ col=_alpha(
376
+ _get(data, "colour", _get(data, "fill", "black")),
377
+ _get(data, "alpha"),
378
+ ),
379
+ lwd=(_get(data, "linewidth", 0.5)) * _PT,
380
+ lty=linetype if linetype else 1,
381
+ lineend=_get(params, "lineend", "butt"),
382
+ ),
383
+ )
384
+
385
+
386
+ def draw_key_vpath(
387
+ data: Dict[str, Any],
388
+ params: Dict[str, Any],
389
+ size: Any = None,
390
+ ) -> Any:
391
+ """Draw a legend key as a vertical segment."""
392
+ return segments_grob(
393
+ x0=0.5,
394
+ y0=0.1,
395
+ x1=0.5,
396
+ y1=0.9,
397
+ gp=Gpar(
398
+ col=_alpha(
399
+ _get(data, "colour", _get(data, "fill", "black")),
400
+ _get(data, "alpha"),
401
+ ),
402
+ lwd=(_get(data, "linewidth", 0.5)) * _PT,
403
+ lty=_get(data, "linetype", 1),
404
+ lineend=_get(params, "lineend", "butt"),
405
+ ),
406
+ )
407
+
408
+
409
+ def draw_key_vline(
410
+ data: Dict[str, Any],
411
+ params: Dict[str, Any],
412
+ size: Any = None,
413
+ ) -> Any:
414
+ """Draw a legend key for vline geoms (full-height vertical segment)."""
415
+ return segments_grob(
416
+ x0=0.5,
417
+ y0=0.0,
418
+ x1=0.5,
419
+ y1=1.0,
420
+ gp=Gpar(
421
+ col=_alpha(
422
+ _get(data, "colour", _get(data, "fill", "black")),
423
+ _get(data, "alpha"),
424
+ ),
425
+ lwd=(_get(data, "linewidth", 0.5)) * _PT,
426
+ lty=_get(data, "linetype", 1),
427
+ lineend=_get(params, "lineend", "butt"),
428
+ ),
429
+ )
430
+
431
+
432
+ def draw_key_timeseries(
433
+ data: Dict[str, Any],
434
+ params: Dict[str, Any],
435
+ size: Any = None,
436
+ ) -> Any:
437
+ """Draw a legend key for time-series geoms (wiggle line)."""
438
+ linetype = _get(data, "linetype")
439
+ if linetype is None:
440
+ linetype = 0
441
+ return lines_grob(
442
+ x=[0.0, 0.4, 0.6, 1.0],
443
+ y=[0.1, 0.6, 0.4, 0.9],
444
+ gp=Gpar(
445
+ col=_alpha(
446
+ _get(data, "colour", _get(data, "fill", "black")),
447
+ _get(data, "alpha"),
448
+ ),
449
+ lwd=(_get(data, "linewidth", 0.5)) * _PT,
450
+ lty=linetype if linetype else 1,
451
+ lineend=_get(params, "lineend", "butt"),
452
+ linejoin=_get(params, "linejoin", "round"),
453
+ ),
454
+ )