plot-io 0.12.0__py3-none-win_amd64.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.
- plot_io/__init__.py +73 -0
- plot_io/_methods.py +1691 -0
- plot_io/_native/__init__.py +199 -0
- plot_io/_native/__main__.py +197 -0
- plot_io/_native/_api.py +457 -0
- plot_io/_native/bin/windows-x86_64.dll +0 -0
- plot_io/_native/kernels.py +335 -0
- plot_io/_native/manifest.json +49 -0
- plot_io/axis.py +1347 -0
- plot_io/boxes.py +1156 -0
- plot_io/canvas.py +389 -0
- plot_io/color/__init__.py +3 -0
- plot_io/color/data.py +1646 -0
- plot_io/color/maps.py +922 -0
- plot_io/color/values.py +295 -0
- plot_io/color/variants.py +1246 -0
- plot_io/colorbar.py +1426 -0
- plot_io/columns.py +614 -0
- plot_io/decorations.py +920 -0
- plot_io/defaults.py +809 -0
- plot_io/density.py +113 -0
- plot_io/ext.py +68 -0
- plot_io/facets.py +240 -0
- plot_io/figure.py +788 -0
- plot_io/formatters.py +97 -0
- plot_io/genome/__init__.py +17 -0
- plot_io/genome/adapters.py +356 -0
- plot_io/genome/combine.py +123 -0
- plot_io/genome/contacts.py +508 -0
- plot_io/genome/intervals.py +750 -0
- plot_io/genome/lanes.py +191 -0
- plot_io/genome/layout.py +184 -0
- plot_io/genome/links.py +364 -0
- plot_io/genome/pack.py +27 -0
- plot_io/genome/readers.py +145 -0
- plot_io/genome/regions.py +228 -0
- plot_io/genome/scale.py +349 -0
- plot_io/genome/series.py +344 -0
- plot_io/genome/signal.py +621 -0
- plot_io/genome/sites.py +782 -0
- plot_io/genome/sources.py +459 -0
- plot_io/genome/testing.py +161 -0
- plot_io/geometry.py +289 -0
- plot_io/groups.py +308 -0
- plot_io/guides.py +503 -0
- plot_io/helpers/__init__.py +17 -0
- plot_io/helpers/clustermap.py +202 -0
- plot_io/helpers/dendrogram.py +172 -0
- plot_io/helpers/grids.py +304 -0
- plot_io/helpers/qq.py +334 -0
- plot_io/helpers/raincloud.py +249 -0
- plot_io/helpers/tree.py +214 -0
- plot_io/helpers/volcano.py +505 -0
- plot_io/hints.py +125 -0
- plot_io/kernels.py +740 -0
- plot_io/labels.py +566 -0
- plot_io/layers/__init__.py +100 -0
- plot_io/layers/base.py +630 -0
- plot_io/layers/context.py +87 -0
- plot_io/layers/core.py +446 -0
- plot_io/layers/geoms.py +1362 -0
- plot_io/layers/grammar.py +586 -0
- plot_io/layers/paint.py +614 -0
- plot_io/layers/pipeline.py +170 -0
- plot_io/layers/positions.py +431 -0
- plot_io/layers/stats.py +1088 -0
- plot_io/layout.py +1381 -0
- plot_io/legend.py +605 -0
- plot_io/levels.py +509 -0
- plot_io/limits.py +124 -0
- plot_io/lines.py +42 -0
- plot_io/mapped.py +522 -0
- plot_io/markers.py +110 -0
- plot_io/markup.py +128 -0
- plot_io/numbers.py +354 -0
- plot_io/occupancy.py +295 -0
- plot_io/plot.py +597 -0
- plot_io/presets/__init__.py +51 -0
- plot_io/presets/_util.py +153 -0
- plot_io/presets/area.py +145 -0
- plot_io/presets/bar.py +261 -0
- plot_io/presets/box.py +400 -0
- plot_io/presets/catpoints.py +177 -0
- plot_io/presets/contour.py +353 -0
- plot_io/presets/curves.py +30 -0
- plot_io/presets/dots.py +355 -0
- plot_io/presets/ecdf.py +97 -0
- plot_io/presets/errorbar.py +106 -0
- plot_io/presets/errors.py +296 -0
- plot_io/presets/fill.py +74 -0
- plot_io/presets/heatmap.py +322 -0
- plot_io/presets/hexbin.py +198 -0
- plot_io/presets/hist.py +391 -0
- plot_io/presets/hist2d.py +87 -0
- plot_io/presets/kde.py +162 -0
- plot_io/presets/kde2d.py +147 -0
- plot_io/presets/line.py +143 -0
- plot_io/presets/pie.py +502 -0
- plot_io/presets/regression.py +115 -0
- plot_io/presets/scatter.py +194 -0
- plot_io/presets/stem.py +100 -0
- plot_io/presets/violin.py +323 -0
- plot_io/py.typed +0 -0
- plot_io/registry.py +82 -0
- plot_io/render.py +480 -0
- plot_io/rows.py +491 -0
- plot_io/scales.py +103 -0
- plot_io/seams.py +138 -0
- plot_io/settings.py +807 -0
- plot_io/shapes.py +66 -0
- plot_io/sharing.py +232 -0
- plot_io/sizemaps.py +97 -0
- plot_io/spec.py +240 -0
- plot_io/states.py +216 -0
- plot_io/styles/__init__.py +307 -0
- plot_io/styles/library.py +397 -0
- plot_io/tables.py +138 -0
- plot_io/text.py +412 -0
- plot_io/ticks.py +400 -0
- plot_io/times.py +287 -0
- plot_io/titles.py +225 -0
- plot_io/transform.py +114 -0
- plot_io/types.py +13604 -0
- plot_io/units.py +768 -0
- plot_io/validators.py +1029 -0
- plot_io/values.py +190 -0
- plot_io-0.12.0.dist-info/METADATA +215 -0
- plot_io-0.12.0.dist-info/RECORD +130 -0
- plot_io-0.12.0.dist-info/WHEEL +4 -0
- 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)
|