plot-io 0.12.0__py3-none-win_arm64.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 (130) hide show
  1. plot_io/__init__.py +73 -0
  2. plot_io/_methods.py +1691 -0
  3. plot_io/_native/__init__.py +199 -0
  4. plot_io/_native/__main__.py +197 -0
  5. plot_io/_native/_api.py +457 -0
  6. plot_io/_native/bin/windows-arm64.dll +0 -0
  7. plot_io/_native/kernels.py +335 -0
  8. plot_io/_native/manifest.json +49 -0
  9. plot_io/axis.py +1347 -0
  10. plot_io/boxes.py +1156 -0
  11. plot_io/canvas.py +389 -0
  12. plot_io/color/__init__.py +3 -0
  13. plot_io/color/data.py +1646 -0
  14. plot_io/color/maps.py +922 -0
  15. plot_io/color/values.py +295 -0
  16. plot_io/color/variants.py +1246 -0
  17. plot_io/colorbar.py +1426 -0
  18. plot_io/columns.py +614 -0
  19. plot_io/decorations.py +920 -0
  20. plot_io/defaults.py +809 -0
  21. plot_io/density.py +113 -0
  22. plot_io/ext.py +68 -0
  23. plot_io/facets.py +240 -0
  24. plot_io/figure.py +788 -0
  25. plot_io/formatters.py +97 -0
  26. plot_io/genome/__init__.py +17 -0
  27. plot_io/genome/adapters.py +356 -0
  28. plot_io/genome/combine.py +123 -0
  29. plot_io/genome/contacts.py +508 -0
  30. plot_io/genome/intervals.py +750 -0
  31. plot_io/genome/lanes.py +191 -0
  32. plot_io/genome/layout.py +184 -0
  33. plot_io/genome/links.py +364 -0
  34. plot_io/genome/pack.py +27 -0
  35. plot_io/genome/readers.py +145 -0
  36. plot_io/genome/regions.py +228 -0
  37. plot_io/genome/scale.py +349 -0
  38. plot_io/genome/series.py +344 -0
  39. plot_io/genome/signal.py +621 -0
  40. plot_io/genome/sites.py +782 -0
  41. plot_io/genome/sources.py +459 -0
  42. plot_io/genome/testing.py +161 -0
  43. plot_io/geometry.py +289 -0
  44. plot_io/groups.py +308 -0
  45. plot_io/guides.py +503 -0
  46. plot_io/helpers/__init__.py +17 -0
  47. plot_io/helpers/clustermap.py +202 -0
  48. plot_io/helpers/dendrogram.py +172 -0
  49. plot_io/helpers/grids.py +304 -0
  50. plot_io/helpers/qq.py +334 -0
  51. plot_io/helpers/raincloud.py +249 -0
  52. plot_io/helpers/tree.py +214 -0
  53. plot_io/helpers/volcano.py +505 -0
  54. plot_io/hints.py +125 -0
  55. plot_io/kernels.py +740 -0
  56. plot_io/labels.py +566 -0
  57. plot_io/layers/__init__.py +100 -0
  58. plot_io/layers/base.py +630 -0
  59. plot_io/layers/context.py +87 -0
  60. plot_io/layers/core.py +446 -0
  61. plot_io/layers/geoms.py +1362 -0
  62. plot_io/layers/grammar.py +586 -0
  63. plot_io/layers/paint.py +614 -0
  64. plot_io/layers/pipeline.py +170 -0
  65. plot_io/layers/positions.py +431 -0
  66. plot_io/layers/stats.py +1088 -0
  67. plot_io/layout.py +1381 -0
  68. plot_io/legend.py +605 -0
  69. plot_io/levels.py +509 -0
  70. plot_io/limits.py +124 -0
  71. plot_io/lines.py +42 -0
  72. plot_io/mapped.py +522 -0
  73. plot_io/markers.py +110 -0
  74. plot_io/markup.py +128 -0
  75. plot_io/numbers.py +354 -0
  76. plot_io/occupancy.py +295 -0
  77. plot_io/plot.py +597 -0
  78. plot_io/presets/__init__.py +51 -0
  79. plot_io/presets/_util.py +153 -0
  80. plot_io/presets/area.py +145 -0
  81. plot_io/presets/bar.py +261 -0
  82. plot_io/presets/box.py +400 -0
  83. plot_io/presets/catpoints.py +177 -0
  84. plot_io/presets/contour.py +353 -0
  85. plot_io/presets/curves.py +30 -0
  86. plot_io/presets/dots.py +355 -0
  87. plot_io/presets/ecdf.py +97 -0
  88. plot_io/presets/errorbar.py +106 -0
  89. plot_io/presets/errors.py +296 -0
  90. plot_io/presets/fill.py +74 -0
  91. plot_io/presets/heatmap.py +322 -0
  92. plot_io/presets/hexbin.py +198 -0
  93. plot_io/presets/hist.py +391 -0
  94. plot_io/presets/hist2d.py +87 -0
  95. plot_io/presets/kde.py +162 -0
  96. plot_io/presets/kde2d.py +147 -0
  97. plot_io/presets/line.py +143 -0
  98. plot_io/presets/pie.py +502 -0
  99. plot_io/presets/regression.py +115 -0
  100. plot_io/presets/scatter.py +194 -0
  101. plot_io/presets/stem.py +100 -0
  102. plot_io/presets/violin.py +323 -0
  103. plot_io/py.typed +0 -0
  104. plot_io/registry.py +82 -0
  105. plot_io/render.py +480 -0
  106. plot_io/rows.py +491 -0
  107. plot_io/scales.py +103 -0
  108. plot_io/seams.py +138 -0
  109. plot_io/settings.py +807 -0
  110. plot_io/shapes.py +66 -0
  111. plot_io/sharing.py +232 -0
  112. plot_io/sizemaps.py +97 -0
  113. plot_io/spec.py +240 -0
  114. plot_io/states.py +216 -0
  115. plot_io/styles/__init__.py +307 -0
  116. plot_io/styles/library.py +397 -0
  117. plot_io/tables.py +138 -0
  118. plot_io/text.py +412 -0
  119. plot_io/ticks.py +400 -0
  120. plot_io/times.py +287 -0
  121. plot_io/titles.py +225 -0
  122. plot_io/transform.py +114 -0
  123. plot_io/types.py +13604 -0
  124. plot_io/units.py +768 -0
  125. plot_io/validators.py +1029 -0
  126. plot_io/values.py +190 -0
  127. plot_io-0.12.0.dist-info/METADATA +215 -0
  128. plot_io-0.12.0.dist-info/RECORD +130 -0
  129. plot_io-0.12.0.dist-info/WHEEL +4 -0
  130. plot_io-0.12.0.dist-info/licenses/LICENSE +28 -0
@@ -0,0 +1,397 @@
1
+ """Bundled styles: the defaults of common plotting libraries, in plot_io's settings.
2
+
3
+ Libraries that specify points (matplotlib, seaborn, ggplot2 — R's linewidth L mm → L ×
4
+ 72.27 / 25.4 × 0.75 pt —, MATLAB, ggthemes) are written in points (``"0.8pt"``); Vega-Lite
5
+ (altair) in px. matplotlib and seaborn values are read from the installed libraries'
6
+ artists, the others from their documented defaults.
7
+ """
8
+
9
+ from . import add_style
10
+
11
+
12
+ def _pt(v: float) -> str:
13
+ """``v`` points, as a length (computed point values: R's line widths)."""
14
+ return f"{v!r}pt"
15
+
16
+
17
+ #: An open "+" (two strokes): matplotlib's and MATLAB's outlier marker
18
+ _PLUS = "M-0.5 0 H0.5 M0 -0.5 V0.5"
19
+
20
+ # -- solid: the base of the library styles --------------------------------------------
21
+
22
+ #: Solid bars, bar histograms, areas and violins, black-outlined boxes, markers without
23
+ #: outline, named colors in the ``base`` variant: what the libraries draw (plot_io's
24
+ #: defaults outline series in their color over a light fill, in the ``forest`` variant).
25
+ add_style("solid", {
26
+ "Hist.shape": "bar",
27
+ "Bar.edge_width": 0.0,
28
+ "Bar.fill_opacity": 1.0,
29
+ "Box.edge_color": "black",
30
+ "Box.fill_opacity": 1.0,
31
+ "Box.median_width": 1.5,
32
+ "Box.max_width": "100%", # the whole slot: no cap
33
+ "Hist.outline": False,
34
+ "Violin.edge_color": "#333333",
35
+ "Violin.fill_opacity": 1.0,
36
+ "Area.fill_opacity": 0.85,
37
+ "Area.edge_width": 0.0,
38
+ "Pie.edge_color": "white",
39
+ "Pie.fill_opacity": 1.0,
40
+ "Bar.seam_color": "none",
41
+ "Pie.seam_color": "none",
42
+ "Marker.size": 5.0, # markers without outline
43
+ "Marker.edge_width": 0.0,
44
+ "Box.marker_size": 3.5, # outliers keep plot_io's
45
+ "Box.marker_edge_width": 0.5,
46
+ "Colorbar.extend_shape": "triangle",
47
+ "Axis.snap": False, # limits at the data plus padding
48
+ "color_variant": "base", # the libraries' colors, unchanged
49
+ })
50
+
51
+ # -- matplotlib (rcParams defaults, ≥ 2.0) --------------------------------------------
52
+
53
+ add_style("matplotlib", {
54
+ "base": "solid",
55
+ "font_family": "DejaVu Sans, Bitstream Vera Sans, Arial, Helvetica, sans-serif",
56
+ "font_size": "10.0pt",
57
+ "Title.font_size": "1.2em", # axes.titlesize: "large"
58
+ "line_width": "1.5pt",
59
+ "qualitative_map": "tab10",
60
+ "sequential_map": "viridis",
61
+ "diverging_map": "coolwarm",
62
+ "Plot.spines": "all",
63
+ "Title.pad": "6.0pt",
64
+ "MainTitle.font_size": "12.0pt", # suptitle: "large", normal weight
65
+ "FigureTitle.font_weight": "normal",
66
+ "Axis.line_width": "0.8pt",
67
+ "Axis.tick_length": "3.5pt",
68
+ "Axis.minor_tick_length": "2.0pt",
69
+ "Axis.tick_width": "0.8pt",
70
+ "Axis.tick_pad": "3.5pt",
71
+ "Axis.label_pad": "4.0pt",
72
+ "Axis.grid_color": "#b0b0b0",
73
+ "Axis.grid_width": "0.8pt",
74
+ "Legend.frame": True,
75
+ "Legend.frame_color": "#cccccc",
76
+ "Legend.frame_width": "1.0pt",
77
+ "Legend.frame_opacity": 0.8,
78
+ "Legend.frame_radius": "3.0pt",
79
+ "Legend.row_height": "1.5em",
80
+ "Legend.inside": "best", # legend.loc: "best" (never outside)
81
+ "Scatter.size": "6.0pt",
82
+ "Line.marker_size": "6.0pt",
83
+ "Box.color": "none",
84
+ "Box.edge_width": "1.0pt",
85
+ "Box.median_color": "C1",
86
+ "Box.median_width": "1.0pt",
87
+ "Box.width": "50%",
88
+ "Box.marker_color": "none",
89
+ "Box.marker_edge_color": "black",
90
+ "Box.marker_edge_width": "1.0pt",
91
+ "Box.marker_size": "6.0pt",
92
+ "Colorbar.style": "bar", # fig.colorbar: location "right", shrink 1
93
+ "Colorbar.side": "right",
94
+ "Colorbar.frame": True,
95
+ "Colorbar.frame_color": "black",
96
+ "Colorbar.frame_width": "0.8pt",
97
+ "Violin.opacity": 0.3, # violinplot bodies: C0 at 0.3, no edge
98
+ "Violin.edge_width": "0.0pt",
99
+ "Violin.inner": False,
100
+ "Strip.size": "6.0pt",
101
+ "Swarm.size": "6.0pt",
102
+ "Pie.edge_width": "0.0pt", # wedges without edges
103
+ })
104
+
105
+ # -- seaborn (0.13: axes_style, plotting_context "notebook", "deep") ---------------------
106
+
107
+ add_style("seaborn", {
108
+ "base": "solid",
109
+ "font_family": "Arial, DejaVu Sans, Liberation Sans, Bitstream Vera Sans, sans-serif",
110
+ "font_size": "12.0pt",
111
+ "text_color": "#262626",
112
+ "line_width": "1.5pt",
113
+ "qualitative_map": "deep",
114
+ "sequential_map": "rocket",
115
+ "diverging_map": "vlag",
116
+ "Plot.background": "#EAEAF2",
117
+ "Plot.spines": "none",
118
+ "Title.font_size": "12.0pt",
119
+ "Title.pad": "6.0pt",
120
+ "MainTitle.font_size": "14.4pt",
121
+ "FigureTitle.font_weight": "normal",
122
+ "Axis.tick_label_font_size": "11.0pt",
123
+ "Axis.tick_length": "0.0pt",
124
+ "Axis.tick_pad": "3.5pt",
125
+ "Axis.label_pad": "4.0pt",
126
+ "Axis.line_width": "1.25pt",
127
+ "Axis.grid": True,
128
+ "Axis.grid_color": "white",
129
+ "Axis.grid_width": "1.0pt",
130
+ "Legend.font_size": "11.0pt",
131
+ "Legend.frame": True,
132
+ "Legend.frame_color": "#cccccc",
133
+ "Legend.frame_width": "1.0pt",
134
+ "Legend.frame_opacity": 0.8,
135
+ "Legend.frame_radius": "3.0pt",
136
+ "Legend.row_height": "1.5em",
137
+ "Legend.inside": "best", # ax.legend: matplotlib's loc "best"
138
+ "Colorbar.style": "bar", # heatmap: figure.colorbar, right, full height
139
+ "Colorbar.side": "right",
140
+ "Scatter.size": "6.0pt",
141
+ "Scatter.edge_color": "white",
142
+ "Scatter.edge_width": "0.48pt",
143
+ "Line.marker_size": "6.0pt",
144
+ "Box.saturation": 0.75,
145
+ "Box.edge_color": "auto",
146
+ "Box.edge_width": "1.0pt",
147
+ "Box.median_width": "1.0pt",
148
+ "Box.marker_color": "none",
149
+ "Box.marker_edge_width": "1.0pt",
150
+ "Box.marker_size": "5.0pt",
151
+ "Bar.saturation": 0.75, # barplot: saturation .75, white 1 pt edges
152
+ "Bar.edge_color": "white",
153
+ "Bar.edge_width": "1.0pt",
154
+ "Bar.error_color": "#424242",
155
+ "Hist.fill_opacity": 0.75, # histplot: alpha (opacity) .75, white edges
156
+ "Hist.edge_color": "white",
157
+ "Hist.edge_width": "1.0pt",
158
+ "Violin.saturation": 0.75, # violinplot: edges and inner box #4c4c4c
159
+ "Violin.edge_color": "#4c4c4c",
160
+ "Violin.edge_width": "1.25pt",
161
+ "Strip.size": "5.0pt", # stripplot/swarmplot: s=25, no edge
162
+ "Strip.edge_width": "0.0pt",
163
+ "Swarm.size": "5.0pt",
164
+ "Swarm.edge_width": "0.0pt",
165
+ "Regression.line_width": "2.25pt", # regplot: lw 1.5 × 1.5, band opacity .15
166
+ "Regression.band_opacity": 0.15,
167
+ "Regression.marker_size": "6.0pt",
168
+ })
169
+
170
+ # -- ggplot2 (theme_grey(base_size = 11), hue_pal, scale_colour_gradient) -----------------
171
+
172
+ _GG_LINE = 0.5 * 72.27 / 25.4 * 0.75 # base_line_size 0.5 mm → 1.07 pt
173
+
174
+ add_style("ggplot2", {
175
+ "base": "solid",
176
+ "Axis.sticky": False, # padding below bar baselines too
177
+ "font_family": "Helvetica, Arial, Liberation Sans, sans-serif",
178
+ "font_size": "11.0pt",
179
+ "line_width": _pt(_GG_LINE),
180
+ "qualitative_map": "hue",
181
+ "sequential_map": "ggplot2",
182
+ "diverging_map": ["#832424", "#FFFFFF", "#3A3A98"], # scale_*_gradient2: muted red, blue
183
+ "Plot.background": "#EBEBEB",
184
+ "Plot.spines": "none",
185
+ "Title.font_size": "13.2pt",
186
+ "Title.align": "left",
187
+ "Title.pad": "5.5pt",
188
+ "MainTitle.font_size": "13.2pt",
189
+ "FigureTitle.font_weight": "normal",
190
+ "MainTitle.align": "left",
191
+ "Axis.tick_label_font_size": "8.8pt",
192
+ "Axis.tick_label_color": "#4D4D4D",
193
+ "Axis.tick_color": "#333333",
194
+ "Axis.tick_length": "2.75pt",
195
+ "Axis.tick_width": _pt(_GG_LINE),
196
+ "Axis.tick_pad": "2.2pt",
197
+ "Axis.label_pad": "2.75pt",
198
+ "Axis.grid": True,
199
+ "Axis.grid_color": "white",
200
+ "Axis.grid_width": _pt(_GG_LINE),
201
+ "Axis.minor_grid": True,
202
+ "Axis.minor_grid_width": _pt(_GG_LINE / 2),
203
+ "Legend.side": "right",
204
+ "Legend.align": "center", # legend.justification: "center"
205
+ "Legend.font_size": "8.8pt",
206
+ "Legend.glyph_length": "1.8em",
207
+ "Legend.row_height": "1.8em",
208
+ "Legend.pad": "11.0pt",
209
+ "Scatter.size": "4.3pt",
210
+ "Line.marker_size": "4.3pt",
211
+ "Box.color": "white",
212
+ "Box.edge_color": "#333333",
213
+ "Box.edge_width": _pt(_GG_LINE),
214
+ "Box.median_width": _pt(2 * _GG_LINE),
215
+ "Box.width": "75%",
216
+ "Box.cap_length": "0.0pt",
217
+ "Box.marker_color": "black",
218
+ "Box.marker_size": "4.3pt",
219
+ "plain_color": "black", # GeomPoint, GeomLine, GeomDensity: black
220
+ "Bar.plain_color": "#595959", # GeomRect (geom_bar, geom_histogram): grey35
221
+ "Hist.plain_color": "#595959",
222
+ "Area.plain_color": "#333333", # GeomArea, GeomRibbon: grey20
223
+ "Fill.plain_color": "#333333",
224
+ "Colorbar.style": "bar", # guide_colourbar, legend.position "right"
225
+ "Colorbar.side": "right",
226
+ "Colorbar.length": "86.4pt", # 5 × legend.key.size (1.2 lines = 17.28 pt)
227
+ "Colorbar.thickness": "17.28pt",
228
+ "Colorbar.label_position": "top", # vertical: title on top, hjust 0
229
+ "Colorbar.tick_color": "white", # guide_colourbar: white ticks inside
230
+ "Colorbar.tick_direction": "in",
231
+ "Colorbar.tick_length": "2.0pt",
232
+ "Colorbar.mirror": True,
233
+ "Kde.line_width": "1.067pt", # geom_density: black, linewidth 0.5
234
+ "Violin.color": "white", # geom_violin: white fill, grey20 outline
235
+ "Violin.edge_width": "1.067pt",
236
+ "Violin.inner": False,
237
+ "Regression.color": "#3366FF", # geom_smooth: #3366FF, linewidth 1
238
+ "Regression.line_width": "2.134pt",
239
+ "Regression.band_opacity": 0.4,
240
+ "Area.fill_opacity": 1.0,
241
+ })
242
+
243
+ # -- altair (Vega-Lite / Vega default config) -------------------------------------------
244
+
245
+ add_style("altair", {
246
+ "base": "solid",
247
+ "font_family": "sans-serif",
248
+ "font_size": 10.0, # guide-label 10 px
249
+ "line_width": 2.0, # line strokeWidth 2 px
250
+ "qualitative_map": "tableau10",
251
+ "sequential_map": "ylgnbu",
252
+ "Plot.border_color": "#DDDDDD", # view stroke
253
+ "Plot.border_width": 1.0,
254
+ "Title.font_size": 13.0, # group-title 13 px bold
255
+ "Title.font_weight": "bold",
256
+ "Title.pad": 4.0,
257
+ "MainTitle.font_size": 13.0,
258
+ "Axis.label_font_size": 11.0, # guide-title 11 px bold
259
+ "Axis.label_weight": "bold",
260
+ "Axis.line_color": "#888888",
261
+ "Axis.line_width": 1.0,
262
+ "Axis.tick_color": "#888888",
263
+ "Axis.tick_length": 5.0,
264
+ "Axis.tick_width": 1.0,
265
+ "Axis.tick_pad": 2.0,
266
+ "Axis.label_pad": 4.0,
267
+ "Axis.grid": True,
268
+ "Axis.grid_width": 1.0,
269
+ "Axis.padding": 0.0,
270
+ "Axis.snap": True,
271
+ "Axis.include_zero": "auto",
272
+ "Legend.side": "right",
273
+ "Legend.pad": 18.0,
274
+ "Colorbar.style": "bar", # gradient legend: orient right, vertical
275
+ "Colorbar.side": "right",
276
+ "Colorbar.length": 200.0, # gradientLength 200 px
277
+ "Colorbar.thickness": 16.0, # gradientThickness 16 px
278
+ "Colorbar.label_position": "top", # titleOrient "top"
279
+ "Scatter.size": 6.1333, # point size 30 px², stroke 2 px, not filled
280
+ "Scatter.fill": False,
281
+ "Scatter.edge_width": 2.0,
282
+ "Line.marker_size": 6.1333,
283
+ "Box.edge_width": 1.0,
284
+ "Box.median_color": "white",
285
+ "Box.median_width": 2.0,
286
+ "Box.width": "50%",
287
+ "Box.marker_edge_width": 2.0,
288
+ "Box.marker_size": 6.1333,
289
+ "Bar.width": "90%", # band scale paddingInner 0.1
290
+ "Hist.edge_color": "white", # binSpacing 1 px
291
+ "Hist.edge_width": 1.0,
292
+ "Area.fill_opacity": 0.7,
293
+ "Pie.edge_width": 0.0,
294
+ })
295
+
296
+ # -- MATLAB (R2014b+ default property values) -------------------------------------------
297
+
298
+ add_style("matlab", {
299
+ "base": "solid",
300
+ "font_family": "Helvetica, Arial, Liberation Sans, sans-serif",
301
+ "font_size": "10.0pt",
302
+ "text_color": "#262626",
303
+ "line_width": "0.5pt",
304
+ "qualitative_map": "matlab",
305
+ "sequential_map": "parula",
306
+ "Title.font_size": "11.0pt",
307
+ "Title.font_weight": "bold",
308
+ "Title.pad": "5.0pt",
309
+ "MainTitle.font_size": "11.0pt", # sgtitle
310
+ "FigureTitle.font_weight": "normal",
311
+ "Axis.label_font_size": "11.0pt",
312
+ "Axis.line_width": "0.5pt",
313
+ "Axis.tick_direction": "in",
314
+ "Axis.tick_length": "3.2pt",
315
+ "Axis.tick_width": "0.5pt",
316
+ "Axis.grid_color": "#dbdbdb",
317
+ "Axis.padding": "0.0pt",
318
+ "Axis.snap": True,
319
+ "Legend.inside": "top_right",
320
+ "Legend.font_size": "9.0pt",
321
+ "Legend.frame": True,
322
+ "Legend.frame_color": "#262626",
323
+ "Legend.frame_width": "0.5pt",
324
+ "Scatter.size": "6.0pt",
325
+ "Scatter.fill": False,
326
+ "Scatter.edge_width": "0.5pt",
327
+ "Line.marker_size": "6.0pt",
328
+ "Box.color": "none",
329
+ "Box.edge_color": "#0000ff",
330
+ "Box.edge_width": "0.5pt",
331
+ "Box.median_color": "#ff0000",
332
+ "Box.median_width": "0.5pt",
333
+ "Box.whisker_color": "black",
334
+ "Box.whisker_style": "dashed",
335
+ "Box.width": "50%",
336
+ "Box.marker": _PLUS,
337
+ "Box.marker_color": "#ff0000",
338
+ "Box.marker_fill": False,
339
+ "Box.marker_edge_width": "0.5pt",
340
+ "Box.marker_size": "6.0pt",
341
+ "Colorbar.style": "bar", # Location "eastoutside": right, full height
342
+ "Colorbar.side": "right",
343
+ "Colorbar.frame": True,
344
+ "Colorbar.frame_color": "#262626",
345
+ "Bar.edge_color": "black", # bar: black 0.5 edges
346
+ "Bar.edge_width": "0.5pt",
347
+ "Hist.fill_opacity": 0.6, # histogram: FaceAlpha 0.6, black edges
348
+ "Hist.edge_color": "black",
349
+ "Hist.edge_width": "0.5pt",
350
+ "Pie.edge_color": "black",
351
+ "Pie.edge_width": "0.5pt",
352
+ })
353
+
354
+ # -- Tufte (ggthemes theme_tufte, with a range frame) -----------------------------------
355
+
356
+ add_style("tufte", {
357
+ "base": "solid",
358
+ "font_family": "serif",
359
+ "font_size": "11.0pt",
360
+ "MainTitle.font_size": "1.4rem",
361
+ "line_width": "0.5pt",
362
+ "qualitative_map": ["#000000", "#666666", "#999999", "#CCCCCC"],
363
+ "sequential_map": "#E6E6E6, black", # 10 % ink at the low end: a count of 1 shows
364
+ "Title.font_size": "13.2pt",
365
+ "Title.align": "left",
366
+ "FigureTitle.font_weight": "normal",
367
+ "MainTitle.align": "left",
368
+ "Axis.tick_label_font_size": "8.8pt",
369
+ "Axis.tick_label_color": "#4D4D4D",
370
+ "Axis.tick_color": "#333333",
371
+ "Axis.line_color": "#333333",
372
+ "Axis.line_width": "0.5pt",
373
+ "Axis.tick_length": "2.75pt",
374
+ "Axis.tick_width": "0.5pt",
375
+ "Axis.spine_trim": True,
376
+ "Axis.spine_offset": "5.0pt",
377
+ "Legend.side": "right",
378
+ "Legend.align": "center", # ggplot2: legend.justification "center"
379
+ "plain_color": "black", # ggplot2's geoms (as ggplot2's style)
380
+ "Bar.plain_color": "#595959",
381
+ "Hist.plain_color": "#595959",
382
+ "Area.plain_color": "#333333",
383
+ "Fill.plain_color": "#333333",
384
+ "Colorbar.style": "bar", # guide_colourbar (as ggplot2's style)
385
+ "Colorbar.side": "right",
386
+ "Colorbar.length": "86.4pt",
387
+ "Colorbar.thickness": "17.28pt",
388
+ "Colorbar.label_position": "top",
389
+ "Scatter.size": "4.0pt",
390
+ "Box.color": "none",
391
+ "Box.edge_width": "0.5pt",
392
+ "Box.width": "30%",
393
+ "Box.cap_length": "0.0pt",
394
+ "Box.median_width": "0.5pt",
395
+ "Box.marker_color": "black",
396
+ "Box.marker_size": "2.0pt",
397
+ })
plot_io/tables.py ADDED
@@ -0,0 +1,138 @@
1
+ """Columns from tables (``data=``) and grouping of series by a column (``group=``).
2
+
3
+ ``data`` is anything that returns a column for ``data[name]``: a dict of sequences, a
4
+ pandas or polars data frame, a numpy structured array. Columns are read through
5
+ ``__getitem__`` and ``to_numpy()`` when present, so no table library is imported.
6
+
7
+ A call with ``group=labels`` is split into one series per group (a :class:`SeriesGroup`),
8
+ each with the rows of every per-point argument that belong to it.
9
+ """
10
+
11
+ import array
12
+ import math
13
+ import warnings
14
+ from typing import Any
15
+
16
+ __all__ = ["column", "has_column", "SeriesGroup", "MARKER_CYCLE", "LINE_STYLE_CYCLE"]
17
+
18
+ MARKER_CYCLE = ("circle", "square", "triangle_up", "diamond", "triangle_down", "plus",
19
+ "cross", "triangle_left", "triangle_right")
20
+ LINE_STYLE_CYCLE = ("solid", "dashed", "dotted", "dashdot")
21
+
22
+
23
+ def has_column(data: Any, name: str) -> bool:
24
+ try:
25
+ columns = data.columns if hasattr(data, "columns") else None
26
+ if columns is not None and not callable(columns):
27
+ return name in list(columns)
28
+ names = getattr(getattr(data, "dtype", None), "names", None)
29
+ if names is not None:
30
+ return name in names
31
+ if hasattr(data, "keys"):
32
+ return name in data.keys()
33
+ data[name]
34
+ return True
35
+ except (KeyError, IndexError, TypeError, ValueError):
36
+ return False
37
+
38
+
39
+ def column(data: Any, name: str) -> tuple[Any, list[Any] | None]:
40
+ """The column ``name`` of ``data`` and, for categorical columns (pandas
41
+ ``category``), the order of its categories."""
42
+ if not has_column(data, name):
43
+ raise ValueError(f"no column {name!r} in data")
44
+ from .columns import _order
45
+ v = data[name]
46
+ order = _order(v)
47
+ if hasattr(v, "to_numpy"):
48
+ v = v.to_numpy()
49
+ if hasattr(v, "dtype") and getattr(v.dtype, "kind", "") in "OUS":
50
+ v = v.tolist()
51
+ return v, order
52
+
53
+
54
+ def is_missing(v: Any) -> bool:
55
+ return v is None or (isinstance(v, float) and math.isnan(v))
56
+
57
+
58
+ def take(v: Any, idx: list[int]) -> Any:
59
+ """The items ``idx`` of a per-point argument."""
60
+ from .columns import Keys
61
+ if isinstance(v, Keys):
62
+ return v.take(idx)
63
+ if isinstance(v, (list, tuple)):
64
+ return [v[i] for i in idx]
65
+ kind = getattr(getattr(v, "dtype", None), "kind", "")
66
+ if kind in ("M", "m"): # numpy dates keep their type
67
+ return v[idx]
68
+ if kind in ("O", "U", "S"):
69
+ return [v[i] for i in idx]
70
+ try:
71
+ mv = memoryview(v)
72
+ except (TypeError, ValueError):
73
+ mv = None
74
+ if mv is not None and mv.ndim == 1 and not isinstance(v, (str, bytes)):
75
+ from . import kernels
76
+ return kernels.take(v, idx) if len(idx) else array.array("d")
77
+ if mv is not None and mv.ndim == 2:
78
+ rows: Any = v.tolist() if hasattr(v, "tolist") else mv.tolist()
79
+ return [tuple(rows[i]) for i in idx]
80
+ return [v[i] for i in idx]
81
+
82
+
83
+ def group_keys(labels: Any, order: list[Any] | None, given: Any, missing: str) -> tuple[
84
+ list[Any], list[list[int]]]:
85
+ """Group keys in order and the row indices of each."""
86
+ keyed: dict[Any, list[int]] = {}
87
+ for i, lab in enumerate(labels):
88
+ if is_missing(lab):
89
+ if missing == "drop":
90
+ continue
91
+ lab = "nan"
92
+ keyed.setdefault(lab, []).append(i)
93
+ keys = list(keyed)
94
+ if given is not None:
95
+ given = list(given)
96
+ unknown = [k for k in keys if k not in given]
97
+ keys = [k for k in given if k in keyed] + unknown
98
+ elif order is not None:
99
+ keys = [k for k in order if k in keyed] + [k for k in keys if k not in order]
100
+ return keys, [keyed[k] for k in keys]
101
+
102
+
103
+ class SeriesGroup(list):
104
+ """The series of a call with ``group=``, one per group, in group order.
105
+
106
+ ``set(**settings)`` applies to every member; ``group[label]`` is one member (an
107
+ integer index also works); ``labels`` lists the group labels.
108
+ """
109
+
110
+ def __init__(self, members: list[Any], labels: list[Any], title: Any = None) -> None:
111
+ super().__init__(members)
112
+ self.labels = labels
113
+ self.title = title
114
+
115
+ def __getitem__(self, key: Any) -> Any:
116
+ if isinstance(key, (int, slice)) and not (isinstance(key, int) and key in self.labels):
117
+ return super().__getitem__(key)
118
+ try:
119
+ return super().__getitem__(self.labels.index(key))
120
+ except ValueError:
121
+ raise KeyError(key) from None
122
+
123
+ def set(self, **settings: Any) -> "SeriesGroup":
124
+ for s in self:
125
+ s.set(**settings)
126
+ return self
127
+
128
+ @property
129
+ def plot(self) -> Any:
130
+ return self[0].plot if len(self) else None
131
+
132
+ def __repr__(self) -> str:
133
+ return f"SeriesGroup({', '.join(map(repr, self.labels))})"
134
+
135
+
136
+ def color_name_warning(name: str) -> None:
137
+ warnings.warn(f"{name!r} is both a column and a color name; using the column",
138
+ stacklevel=4)