ggh4x-python 0.3.1.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 (64) hide show
  1. ggh4x/__init__.py +140 -0
  2. ggh4x/_aimed_text_grob.py +432 -0
  3. ggh4x/_borrowed_ggplot2.py +273 -0
  4. ggh4x/_cli.py +84 -0
  5. ggh4x/_datasets.py +106 -0
  6. ggh4x/_download.py +111 -0
  7. ggh4x/_facet_helpers.py +313 -0
  8. ggh4x/_facet_utils.py +649 -0
  9. ggh4x/_gap_grobs.py +606 -0
  10. ggh4x/_registry.py +10 -0
  11. ggh4x/_rlang.py +93 -0
  12. ggh4x/_utils.py +150 -0
  13. ggh4x/_vctrs.py +233 -0
  14. ggh4x/conveniences.py +601 -0
  15. ggh4x/coord_axes_inside.py +380 -0
  16. ggh4x/element_part_rect.py +545 -0
  17. ggh4x/facet_grid2.py +1018 -0
  18. ggh4x/facet_manual.py +901 -0
  19. ggh4x/facet_nested.py +776 -0
  20. ggh4x/facet_nested_wrap.py +193 -0
  21. ggh4x/facet_wrap2.py +896 -0
  22. ggh4x/geom_box.py +536 -0
  23. ggh4x/geom_outline_point.py +444 -0
  24. ggh4x/geom_pointpath.py +259 -0
  25. ggh4x/geom_polygonraster.py +252 -0
  26. ggh4x/geom_rectrug.py +489 -0
  27. ggh4x/geom_text_aimed.py +279 -0
  28. ggh4x/guide_stringlegend.py +354 -0
  29. ggh4x/help_secondary.py +549 -0
  30. ggh4x/multiscale/__init__.py +51 -0
  31. ggh4x/multiscale/_multiscale_add.py +207 -0
  32. ggh4x/multiscale/scale_listed.py +167 -0
  33. ggh4x/multiscale/scale_manual.py +478 -0
  34. ggh4x/multiscale/scale_multi.py +393 -0
  35. ggh4x/panel_scales/__init__.py +58 -0
  36. ggh4x/panel_scales/at_panel.py +115 -0
  37. ggh4x/panel_scales/facetted_pos_scales.py +647 -0
  38. ggh4x/panel_scales/force_panelsize.py +411 -0
  39. ggh4x/panel_scales/scale_facet.py +222 -0
  40. ggh4x/position_disjoint_ranges.py +229 -0
  41. ggh4x/position_lineartrans.py +242 -0
  42. ggh4x/py.typed +0 -0
  43. ggh4x/resources/faithful.csv +273 -0
  44. ggh4x/resources/iris.csv +151 -0
  45. ggh4x/resources/mtcars.csv +33 -0
  46. ggh4x/resources/pressure.csv +20 -0
  47. ggh4x/resources/volcano.csv +87 -0
  48. ggh4x/save.py +255 -0
  49. ggh4x/stat_difference.py +388 -0
  50. ggh4x/stat_funxy.py +436 -0
  51. ggh4x/stat_rle.py +290 -0
  52. ggh4x/stat_rollingkernel.py +369 -0
  53. ggh4x/stat_theodensity.py +681 -0
  54. ggh4x/strip_nested.py +448 -0
  55. ggh4x/strip_split.py +687 -0
  56. ggh4x/strip_tag.py +636 -0
  57. ggh4x/strip_themed.py +232 -0
  58. ggh4x/strip_vanilla.py +1464 -0
  59. ggh4x/themes.py +31 -0
  60. ggh4x/themes_ggh4x.py +67 -0
  61. ggh4x_python-0.3.1.9000.dist-info/METADATA +40 -0
  62. ggh4x_python-0.3.1.9000.dist-info/RECORD +64 -0
  63. ggh4x_python-0.3.1.9000.dist-info/WHEEL +4 -0
  64. ggh4x_python-0.3.1.9000.dist-info/licenses/LICENSE +3 -0
ggh4x/strip_themed.py ADDED
@@ -0,0 +1,232 @@
1
+ """Themed strips for ggh4x facets (port of ggh4x ``strip_themed.R``).
2
+
3
+ This module ports :class:`StripThemed` -- the R ggproto object whose *class
4
+ string* is ``"StripElemental"`` (the object is named ``StripThemed``) -- and the
5
+ :func:`strip_themed` constructor.
6
+
7
+ ``StripThemed`` extends the base :class:`ggh4x.strip_vanilla.Strip`. It allows
8
+ per-strip theming: the user supplies *lists* of
9
+ :class:`~ggplot2_py.theme_elements.ElementText` /
10
+ :class:`~ggplot2_py.theme_elements.ElementRect` objects (``text_x`` / ``text_y``
11
+ / ``background_x`` / ``background_y``) that are inherited onto the theme defaults
12
+ (via :func:`ggh4x.strip_vanilla.inherit_element`) and mapped either across strips
13
+ (``rep_len`` recycling) or across the layers of a strip (``by_layer_*``).
14
+
15
+ R source: ``ggh4x/R/strip_themed.R`` (the ``StripThemed`` /
16
+ ``"StripElemental"`` ggproto and the ``strip_themed()`` constructor). The
17
+ helpers ``validate_element_list`` / ``inherit_element`` live in
18
+ :mod:`ggh4x.strip_vanilla`.
19
+
20
+ Notes
21
+ -----
22
+ * **Only override is ``setup_elements``.** Everything else (``setup`` /
23
+ ``get_strips`` / ``assemble_strip`` / ``build_strip`` / the self-less
24
+ ``init_strip`` / ``draw_labels`` / ``finish_strip`` / ``incorporate_*``) is
25
+ inherited unchanged from :class:`Strip`. The base
26
+ :func:`ggh4x.strip_vanilla._init_strip_impl` already reads
27
+ ``elements["by_layer"][aes]`` (defaulting to ``False`` when absent), so the
28
+ ``by_layer`` dict produced here flows straight through.
29
+ * **``by_layer`` dict.** ``setup_elements`` adds ``by_layer = {"x": ..., "y":
30
+ ...}`` to the returned element bundle (the base ``Strip.setup_elements`` does
31
+ not).
32
+ * **Per-side independent inherit.** R re-runs ``inherit_element`` for
33
+ ``text$x$top`` *and* ``text$x$bottom`` against the *same* user list, so the
34
+ top and bottom calc-element defaults are inherited independently; this port
35
+ does the same.
36
+ """
37
+
38
+ from __future__ import annotations
39
+
40
+ from typing import Any, Dict
41
+
42
+ from ggplot2_py import calc_element, element_grob
43
+ from ggplot2_py.ggproto import ggproto
44
+
45
+ from ggh4x._rlang import arg_match0
46
+ from ggh4x.strip_vanilla import (
47
+ Strip,
48
+ _placement_inside,
49
+ inherit_element,
50
+ validate_element_list,
51
+ )
52
+ from grid_py import convert_unit
53
+
54
+ __all__ = ["StripThemed", "strip_themed"]
55
+
56
+
57
+ class StripThemed(Strip):
58
+ """Strip with individually themed boxes and texts (R ``"StripElemental"``).
59
+
60
+ Subclass of :class:`ggh4x.strip_vanilla.Strip`. Overrides only
61
+ :meth:`setup_elements`; the rest of the strip machinery is inherited.
62
+
63
+ Attributes
64
+ ----------
65
+ given_elements : dict
66
+ The user-supplied element lists and ``by_layer`` flags, set by
67
+ :func:`strip_themed` (keys ``text_x`` / ``text_y`` / ``background_x`` /
68
+ ``background_y`` / ``by_layer_x`` / ``by_layer_y``).
69
+
70
+ Notes
71
+ -----
72
+ The R class string is ``"StripElemental"`` even though the object is named
73
+ ``StripThemed``. ``_class_name`` is set to ``"StripElemental"`` for repr
74
+ parity (the :func:`strip_themed` clone reuses the Python class name, but the
75
+ base singleton reports ``StripElemental``).
76
+ """
77
+
78
+ _class_name = "StripElemental"
79
+
80
+ given_elements: Dict[str, Any] = {}
81
+
82
+ def setup_elements(self, theme: Any, type: str) -> Dict[str, Any]:
83
+ """Resolve per-strip themed elements, with a ``by_layer`` dict.
84
+
85
+ Port of R ``StripThemed$setup_elements`` (``strip_themed.R:119-182``).
86
+ Like :meth:`Strip.setup_elements` but resolves the backgrounds and
87
+ per-side texts from the user-supplied element lists in
88
+ ``self.given_elements``, each inherited onto the ``calc_element`` theme
89
+ default via :func:`inherit_element`; backgrounds are then turned into
90
+ grobs via :func:`element_grob`. Adds a ``by_layer`` dict.
91
+
92
+ Parameters
93
+ ----------
94
+ theme : Theme
95
+ The active theme.
96
+ type : str
97
+ ``"wrap"`` selects ``strip.switch.pad.wrap`` padding, anything else
98
+ (``"grid"``) ``strip.switch.pad.grid``. Kept as the parameter name
99
+ ``type`` for facet-call compatibility.
100
+
101
+ Returns
102
+ -------
103
+ dict
104
+ ``{"padding", "background", "text", "inside", "by_layer"}``. The
105
+ ``background`` values are *grobs* (single grob when the user gave no
106
+ list, else a list of grobs); ``text`` values are elements (single
107
+ element from ``calc_element`` or a list of inherited elements).
108
+ """
109
+ given = self.given_elements
110
+
111
+ # --- backgrounds: calc_element default, inherit user list, to grob ----
112
+ bg_x_default = calc_element("strip.background.x", theme)
113
+ bg_y_default = calc_element("strip.background.y", theme)
114
+ background: Dict[str, Any] = {}
115
+ if given.get("background_x") is not None:
116
+ inherited = [inherit_element(el, bg_x_default) for el in given["background_x"]]
117
+ background["x"] = [element_grob(el) for el in inherited]
118
+ else:
119
+ background["x"] = element_grob(bg_x_default)
120
+ if given.get("background_y") is not None:
121
+ inherited = [inherit_element(el, bg_y_default) for el in given["background_y"]]
122
+ background["y"] = [element_grob(el) for el in inherited]
123
+ else:
124
+ background["y"] = element_grob(bg_y_default)
125
+
126
+ # --- texts: per-side calc_element default, optionally inherit list ----
127
+ text: Dict[str, Dict[str, Any]] = {
128
+ "x": {
129
+ "top": calc_element("strip.text.x.top", theme),
130
+ "bottom": calc_element("strip.text.x.bottom", theme),
131
+ },
132
+ "y": {
133
+ "left": calc_element("strip.text.y.left", theme),
134
+ "right": calc_element("strip.text.y.right", theme),
135
+ },
136
+ }
137
+ if given.get("text_x") is not None:
138
+ text["x"]["top"] = [
139
+ inherit_element(el, text["x"]["top"]) for el in given["text_x"]
140
+ ]
141
+ text["x"]["bottom"] = [
142
+ inherit_element(el, text["x"]["bottom"]) for el in given["text_x"]
143
+ ]
144
+ if given.get("text_y") is not None:
145
+ text["y"]["left"] = [
146
+ inherit_element(el, text["y"]["left"]) for el in given["text_y"]
147
+ ]
148
+ text["y"]["right"] = [
149
+ inherit_element(el, text["y"]["right"]) for el in given["text_y"]
150
+ ]
151
+
152
+ inside = {
153
+ "x": _placement_inside(calc_element("strip.placement.x", theme)),
154
+ "y": _placement_inside(calc_element("strip.placement.y", theme)),
155
+ }
156
+ pad_name = (
157
+ "strip.switch.pad.wrap" if type == "wrap" else "strip.switch.pad.grid"
158
+ )
159
+ padding = convert_unit(calc_element(pad_name, theme), "cm")
160
+
161
+ by_layer = {
162
+ "x": bool(given.get("by_layer_x", False)),
163
+ "y": bool(given.get("by_layer_y", False)),
164
+ }
165
+
166
+ return {
167
+ "padding": padding,
168
+ "background": background,
169
+ "text": text,
170
+ "inside": inside,
171
+ "by_layer": by_layer,
172
+ }
173
+
174
+
175
+ # R's ``StripThemed`` is a ggproto *instance* used as the parent of every
176
+ # ``strip_themed()`` clone; this module-level singleton plays that role.
177
+ _STRIP_THEMED_SINGLETON: "StripThemed" = StripThemed()
178
+
179
+
180
+ def strip_themed(
181
+ clip: str = "inherit",
182
+ size: str = "constant",
183
+ text_x: Any = None,
184
+ text_y: Any = None,
185
+ background_x: Any = None,
186
+ background_y: Any = None,
187
+ by_layer_x: bool = False,
188
+ by_layer_y: bool = False,
189
+ ) -> StripThemed:
190
+ """Create a strip with individually themed boxes and texts.
191
+
192
+ Port of R ``strip_themed()`` (``strip_themed.R:76-106``).
193
+
194
+ Parameters
195
+ ----------
196
+ clip : str, default ``"inherit"``
197
+ Whether labels are clipped to background boxes (``"inherit"`` / ``"on"``
198
+ / ``"off"``).
199
+ size : str, default ``"constant"``
200
+ Whether strip margins across layers are ``"constant"`` or ``"variable"``.
201
+ text_x, text_y : list of ElementText or ElementText or None
202
+ Per-strip (or per-layer, see *by_layer_*) text elements. ``None`` means
203
+ the global theme applies; ``element_blank()`` omits the text.
204
+ background_x, background_y : list of ElementRect or ElementRect or None
205
+ Per-strip (or per-layer) background rectangles.
206
+ by_layer_x, by_layer_y : bool, default ``False``
207
+ When ``True`` map elements to the different *layers* of a strip; when
208
+ ``False`` map to individual strips with ``rep_len`` recycling.
209
+
210
+ Returns
211
+ -------
212
+ StripThemed
213
+ A ``StripThemed`` ggproto instance usable in ggh4x facets.
214
+ """
215
+ params = {
216
+ "clip": arg_match0(clip, ["on", "off", "inherit"], arg_name="clip"),
217
+ "size": arg_match0(size, ["constant", "variable"], arg_name="size"),
218
+ }
219
+ given_elements = {
220
+ "text_x": validate_element_list(text_x, "element_text"),
221
+ "text_y": validate_element_list(text_y, "element_text"),
222
+ "background_x": validate_element_list(background_x, "element_rect"),
223
+ "background_y": validate_element_list(background_y, "element_rect"),
224
+ "by_layer_x": bool(by_layer_x),
225
+ "by_layer_y": bool(by_layer_y),
226
+ }
227
+ return ggproto(
228
+ None,
229
+ _STRIP_THEMED_SINGLETON,
230
+ params=params,
231
+ given_elements=given_elements,
232
+ )