plot-io 0.8.0__tar.gz → 0.12.0__tar.gz

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 (373) hide show
  1. plot_io-0.12.0/PKG-INFO +215 -0
  2. plot_io-0.12.0/README.md +199 -0
  3. plot_io-0.12.0/docs/api.md +1275 -0
  4. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/annotated.py +6 -6
  5. plot_io-0.12.0/docs/examples/bars.py +21 -0
  6. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/box_plots.py +4 -4
  7. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/colorbars.py +11 -11
  8. plot_io-0.12.0/docs/examples/density.py +24 -0
  9. plot_io-0.12.0/docs/examples/distributions.py +24 -0
  10. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/dots.py +7 -7
  11. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/error_bars.py +3 -3
  12. plot_io-0.12.0/docs/examples/facets.py +19 -0
  13. plot_io-0.12.0/docs/examples/genome_matrices.py +59 -0
  14. plot_io-0.12.0/docs/examples/genome_regions.py +53 -0
  15. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/genome_tracks.py +32 -18
  16. plot_io-0.12.0/docs/examples/grids2d.py +24 -0
  17. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/groups.py +6 -6
  18. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/heatmap.py +4 -4
  19. plot_io-0.12.0/docs/examples/helpers.py +61 -0
  20. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/large_data.py +5 -6
  21. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/layouts.py +4 -4
  22. plot_io-0.12.0/docs/examples/levels.py +40 -0
  23. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/line_band.py +4 -4
  24. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/scales.py +5 -5
  25. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/scatter_groups.py +3 -3
  26. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/shared_colorbar.py +4 -4
  27. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/shared_legend.py +11 -11
  28. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/shared_sizes.py +6 -6
  29. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/styles.py +19 -12
  30. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/time_twin.py +4 -4
  31. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/titles.py +5 -5
  32. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/units.py +12 -11
  33. {plot_io-0.8.0 → plot_io-0.12.0/docs}/examples/variable_fonts.py +6 -6
  34. plot_io-0.12.0/docs/examples.md +1473 -0
  35. plot_io-0.12.0/docs/from_matplotlib.md +149 -0
  36. plot_io-0.12.0/docs/plots/area.md +64 -0
  37. plot_io-0.12.0/docs/plots/bar.md +89 -0
  38. plot_io-0.12.0/docs/plots/bed.md +105 -0
  39. plot_io-0.12.0/docs/plots/bigwig.md +107 -0
  40. plot_io-0.12.0/docs/plots/box.md +98 -0
  41. plot_io-0.12.0/docs/plots/clustermap.md +34 -0
  42. plot_io-0.12.0/docs/plots/contour.md +76 -0
  43. plot_io-0.12.0/docs/plots/dendrogram.md +49 -0
  44. plot_io-0.12.0/docs/plots/dots.md +88 -0
  45. plot_io-0.12.0/docs/plots/ecdf.md +63 -0
  46. plot_io-0.12.0/docs/plots/errorbar.md +77 -0
  47. plot_io-0.12.0/docs/plots/facet.md +30 -0
  48. plot_io-0.12.0/docs/plots/fill.md +65 -0
  49. plot_io-0.12.0/docs/plots/genes.md +39 -0
  50. plot_io-0.12.0/docs/plots/gtf.md +43 -0
  51. plot_io-0.12.0/docs/plots/heatmap.md +74 -0
  52. plot_io-0.12.0/docs/plots/hexbin.md +65 -0
  53. plot_io-0.12.0/docs/plots/hic.md +109 -0
  54. plot_io-0.12.0/docs/plots/hist.md +87 -0
  55. plot_io-0.12.0/docs/plots/hist2d.md +39 -0
  56. plot_io-0.12.0/docs/plots/joint.md +29 -0
  57. plot_io-0.12.0/docs/plots/kde.md +74 -0
  58. plot_io-0.12.0/docs/plots/kde2d.md +46 -0
  59. plot_io-0.12.0/docs/plots/line.md +100 -0
  60. plot_io-0.12.0/docs/plots/linkage.md +34 -0
  61. plot_io-0.12.0/docs/plots/links.md +63 -0
  62. plot_io-0.12.0/docs/plots/ma.md +49 -0
  63. plot_io-0.12.0/docs/plots/manhattan.md +51 -0
  64. plot_io-0.12.0/docs/plots/pairs.md +31 -0
  65. plot_io-0.12.0/docs/plots/pie.md +76 -0
  66. plot_io-0.12.0/docs/plots/qq.md +67 -0
  67. plot_io-0.12.0/docs/plots/raincloud.md +86 -0
  68. plot_io-0.12.0/docs/plots/regression.md +91 -0
  69. plot_io-0.12.0/docs/plots/scatter.md +99 -0
  70. plot_io-0.12.0/docs/plots/site_heatmap.md +86 -0
  71. plot_io-0.12.0/docs/plots/site_profile.md +59 -0
  72. plot_io-0.12.0/docs/plots/stem.md +73 -0
  73. plot_io-0.12.0/docs/plots/strip.md +83 -0
  74. plot_io-0.12.0/docs/plots/swarm.md +81 -0
  75. plot_io-0.12.0/docs/plots/violin.md +84 -0
  76. plot_io-0.12.0/docs/plots/volcano.md +57 -0
  77. plot_io-0.12.0/docs/reference/axis.md +151 -0
  78. plot_io-0.12.0/docs/reference/canvas.md +48 -0
  79. plot_io-0.12.0/docs/reference/color_axes.md +295 -0
  80. plot_io-0.12.0/docs/reference/colorbars.md +95 -0
  81. plot_io-0.12.0/docs/reference/decorations.md +176 -0
  82. plot_io-0.12.0/docs/reference/figure.md +300 -0
  83. plot_io-0.12.0/docs/reference/figure_rows.md +69 -0
  84. plot_io-0.12.0/docs/reference/legends.md +118 -0
  85. plot_io-0.12.0/docs/reference/plot.md +220 -0
  86. plot_io-0.12.0/docs/reference/sets.md +107 -0
  87. plot_io-0.12.0/docs/reference/titles.md +107 -0
  88. plot_io-0.12.0/docs/reference/tracks.md +70 -0
  89. plot_io-0.12.0/docs/tutorial.md +159 -0
  90. plot_io-0.12.0/hatch_build.py +47 -0
  91. plot_io-0.12.0/plot_io/__init__.py +73 -0
  92. plot_io-0.12.0/plot_io/_methods.py +1691 -0
  93. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/README.md +37 -10
  94. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/__init__.py +22 -11
  95. plot_io-0.12.0/plot_io/_native/__main__.py +197 -0
  96. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/_api.py +65 -3
  97. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/kernels.py +31 -12
  98. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/manifest.json +12 -12
  99. plot_io-0.12.0/plot_io/_native/src/cluster.c +554 -0
  100. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/colormap.c +22 -5
  101. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/plio.h +1 -1
  102. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/plio_api.h +56 -12
  103. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/plot.c +119 -28
  104. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/signatures.c +39 -3
  105. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/stats.c +50 -8
  106. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/axis.py +617 -96
  107. plot_io-0.12.0/plot_io/boxes.py +1156 -0
  108. plot_io-0.12.0/plot_io/canvas.py +389 -0
  109. plot_io-0.12.0/plot_io/color/__init__.py +3 -0
  110. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/color/data.py +66 -38
  111. plot_io-0.12.0/plot_io/color/maps.py +922 -0
  112. plot_io-0.12.0/plot_io/color/values.py +295 -0
  113. plot_io-0.12.0/plot_io/color/variants.py +1246 -0
  114. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/colorbar.py +373 -147
  115. plot_io-0.12.0/plot_io/columns.py +614 -0
  116. plot_io-0.12.0/plot_io/decorations.py +920 -0
  117. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/defaults.py +158 -35
  118. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/density.py +23 -7
  119. plot_io-0.12.0/plot_io/ext.py +68 -0
  120. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/facets.py +69 -24
  121. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/figure.py +195 -68
  122. plot_io-0.12.0/plot_io/formatters.py +97 -0
  123. plot_io-0.12.0/plot_io/genome/__init__.py +17 -0
  124. plot_io-0.12.0/plot_io/genome/adapters.py +356 -0
  125. plot_io-0.12.0/plot_io/genome/combine.py +123 -0
  126. plot_io-0.12.0/plot_io/genome/contacts.py +508 -0
  127. plot_io-0.12.0/plot_io/genome/intervals.py +750 -0
  128. plot_io-0.12.0/plot_io/genome/lanes.py +191 -0
  129. plot_io-0.12.0/plot_io/genome/layout.py +184 -0
  130. plot_io-0.12.0/plot_io/genome/links.py +364 -0
  131. plot_io-0.12.0/plot_io/genome/readers.py +145 -0
  132. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/genome/regions.py +101 -6
  133. plot_io-0.12.0/plot_io/genome/scale.py +349 -0
  134. plot_io-0.12.0/plot_io/genome/series.py +344 -0
  135. plot_io-0.12.0/plot_io/genome/signal.py +621 -0
  136. plot_io-0.12.0/plot_io/genome/sites.py +782 -0
  137. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/genome/sources.py +160 -53
  138. plot_io-0.12.0/plot_io/genome/testing.py +161 -0
  139. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/geometry.py +4 -11
  140. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/groups.py +36 -24
  141. plot_io-0.12.0/plot_io/guides.py +503 -0
  142. plot_io-0.12.0/plot_io/helpers/__init__.py +17 -0
  143. plot_io-0.12.0/plot_io/helpers/clustermap.py +202 -0
  144. plot_io-0.12.0/plot_io/helpers/dendrogram.py +172 -0
  145. plot_io-0.12.0/plot_io/helpers/grids.py +304 -0
  146. plot_io-0.12.0/plot_io/helpers/qq.py +334 -0
  147. plot_io-0.12.0/plot_io/helpers/raincloud.py +249 -0
  148. plot_io-0.12.0/plot_io/helpers/tree.py +214 -0
  149. plot_io-0.12.0/plot_io/helpers/volcano.py +505 -0
  150. plot_io-0.12.0/plot_io/hints.py +125 -0
  151. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/kernels.py +260 -43
  152. plot_io-0.12.0/plot_io/labels.py +566 -0
  153. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/layers/__init__.py +36 -9
  154. plot_io-0.12.0/plot_io/layers/base.py +630 -0
  155. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/layers/context.py +27 -12
  156. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/layers/core.py +192 -21
  157. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/layers/geoms.py +331 -167
  158. plot_io-0.12.0/plot_io/layers/grammar.py +586 -0
  159. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/layers/paint.py +255 -28
  160. plot_io-0.12.0/plot_io/layers/pipeline.py +170 -0
  161. plot_io-0.12.0/plot_io/layers/positions.py +431 -0
  162. plot_io-0.12.0/plot_io/layers/stats.py +1088 -0
  163. plot_io-0.12.0/plot_io/layout.py +1381 -0
  164. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/legend.py +175 -289
  165. plot_io-0.12.0/plot_io/levels.py +509 -0
  166. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/limits.py +47 -18
  167. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/lines.py +11 -7
  168. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/mapped.py +78 -22
  169. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/markers.py +2 -3
  170. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/numbers.py +100 -16
  171. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/occupancy.py +99 -24
  172. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/plot.py +241 -104
  173. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/__init__.py +11 -3
  174. plot_io-0.12.0/plot_io/presets/_util.py +153 -0
  175. plot_io-0.12.0/plot_io/presets/area.py +145 -0
  176. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/bar.py +134 -125
  177. plot_io-0.12.0/plot_io/presets/box.py +400 -0
  178. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/catpoints.py +80 -77
  179. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/contour.py +103 -52
  180. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/curves.py +1 -1
  181. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/dots.py +112 -101
  182. plot_io-0.12.0/plot_io/presets/ecdf.py +97 -0
  183. plot_io-0.12.0/plot_io/presets/errorbar.py +106 -0
  184. plot_io-0.12.0/plot_io/presets/errors.py +296 -0
  185. plot_io-0.12.0/plot_io/presets/fill.py +74 -0
  186. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/heatmap.py +84 -51
  187. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/hexbin.py +49 -35
  188. plot_io-0.12.0/plot_io/presets/hist.py +391 -0
  189. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/hist2d.py +23 -14
  190. plot_io-0.12.0/plot_io/presets/kde.py +162 -0
  191. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/kde2d.py +35 -19
  192. plot_io-0.12.0/plot_io/presets/line.py +143 -0
  193. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/presets/pie.py +131 -86
  194. plot_io-0.12.0/plot_io/presets/regression.py +115 -0
  195. plot_io-0.12.0/plot_io/presets/scatter.py +194 -0
  196. plot_io-0.12.0/plot_io/presets/stem.py +100 -0
  197. plot_io-0.12.0/plot_io/presets/violin.py +323 -0
  198. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/registry.py +15 -21
  199. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/render.py +146 -112
  200. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/rows.py +101 -26
  201. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/scales.py +16 -7
  202. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/seams.py +40 -21
  203. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/settings.py +245 -303
  204. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/shapes.py +8 -7
  205. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/sharing.py +24 -1
  206. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/sizemaps.py +10 -3
  207. plot_io-0.12.0/plot_io/spec.py +240 -0
  208. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/states.py +42 -34
  209. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/styles/__init__.py +36 -6
  210. plot_io-0.12.0/plot_io/styles/library.py +397 -0
  211. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/tables.py +13 -16
  212. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/text.py +135 -12
  213. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/ticks.py +154 -53
  214. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/times.py +82 -11
  215. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/titles.py +43 -6
  216. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/transform.py +7 -1
  217. plot_io-0.12.0/plot_io/types.py +13604 -0
  218. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/units.py +299 -383
  219. plot_io-0.12.0/plot_io/validators.py +1029 -0
  220. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/values.py +40 -23
  221. {plot_io-0.8.0 → plot_io-0.12.0}/pyproject.toml +14 -8
  222. plot_io-0.8.0/tests/fonts/PioTest-Bold.ttf → plot_io-0.12.0/tests/fonts/VioTest-Bold.ttf +0 -0
  223. plot_io-0.8.0/tests/fonts/PioTest-Regular.ttf → plot_io-0.12.0/tests/fonts/VioTest-Regular.ttf +0 -0
  224. plot_io-0.12.0/tests/fuzz_native.py +178 -0
  225. plot_io-0.12.0/tests/golden.json +166 -0
  226. {plot_io-0.8.0 → plot_io-0.12.0}/tests/helpers.py +38 -25
  227. plot_io-0.12.0/tests/preset_ref.json +1656 -0
  228. plot_io-0.12.0/tests/recording.py +871 -0
  229. plot_io-0.12.0/tests/stats_reference.json +8382 -0
  230. plot_io-0.12.0/tests/test_api.py +169 -0
  231. plot_io-0.12.0/tests/test_bars.py +549 -0
  232. plot_io-0.12.0/tests/test_boundary.py +113 -0
  233. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_box.py +38 -10
  234. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_colorbars.py +189 -44
  235. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_decorations.py +50 -17
  236. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_defaults.py +63 -14
  237. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_density.py +44 -41
  238. plot_io-0.12.0/tests/test_distributions.py +458 -0
  239. plot_io-0.12.0/tests/test_docs.py +88 -0
  240. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_dots.py +43 -38
  241. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_edge_cases.py +28 -2
  242. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_entry.py +18 -18
  243. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_figure_title.py +36 -7
  244. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_fonts.py +14 -14
  245. plot_io-0.12.0/tests/test_genome.py +1746 -0
  246. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_geometry.py +22 -22
  247. plot_io-0.12.0/tests/test_golden.py +593 -0
  248. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_grids.py +9 -9
  249. plot_io-0.12.0/tests/test_heatmap.py +147 -0
  250. plot_io-0.12.0/tests/test_invariants.py +36 -0
  251. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_jxl_output.py +2 -5
  252. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_layers.py +48 -22
  253. plot_io-0.12.0/tests/test_layout.py +573 -0
  254. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_limits.py +33 -9
  255. plot_io-0.12.0/tests/test_maps.py +602 -0
  256. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_markers.py +4 -5
  257. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_markup.py +24 -43
  258. plot_io-0.12.0/tests/test_native.py +299 -0
  259. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_numbers.py +7 -7
  260. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_occupancy.py +140 -18
  261. plot_io-0.12.0/tests/test_output.py +468 -0
  262. plot_io-0.12.0/tests/test_pie.py +75 -0
  263. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_reflines.py +40 -9
  264. plot_io-0.12.0/tests/test_registry.py +73 -0
  265. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_rows.py +26 -15
  266. plot_io-0.12.0/tests/test_series.py +249 -0
  267. plot_io-0.12.0/tests/test_settings.py +506 -0
  268. plot_io-0.12.0/tests/test_settings_fuzz.py +22 -0
  269. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_shared_legends.py +70 -13
  270. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_sharing.py +7 -7
  271. plot_io-0.12.0/tests/test_simplify.py +116 -0
  272. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_size_keys.py +24 -14
  273. plot_io-0.12.0/tests/test_stats.py +293 -0
  274. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_style_settings.py +39 -37
  275. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_style_types.py +11 -11
  276. plot_io-0.12.0/tests/test_styles.py +330 -0
  277. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_tables.py +207 -30
  278. plot_io-0.12.0/tests/test_ticks.py +310 -0
  279. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_time_twin.py +47 -10
  280. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_titles.py +24 -30
  281. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_transform.py +27 -10
  282. plot_io-0.12.0/tests/test_typing.py +48 -0
  283. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_units.py +139 -55
  284. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_values.py +107 -81
  285. {plot_io-0.8.0 → plot_io-0.12.0}/tests/test_vocabulary.py +38 -38
  286. plot_io-0.12.0/tests/typing/user_code.py +40 -0
  287. {plot_io-0.8.0 → plot_io-0.12.0}/tools/build_native.py +356 -24
  288. plot_io-0.12.0/tools/gen_api.py +405 -0
  289. plot_io-0.12.0/tools/gen_docs.py +1139 -0
  290. {plot_io-0.8.0 → plot_io-0.12.0}/tools/settings_doc.py +28 -82
  291. plot_io-0.12.0/tools/zig.lock +17 -0
  292. plot_io-0.8.0/API.md +0 -3425
  293. plot_io-0.8.0/EXAMPLES.md +0 -1050
  294. plot_io-0.8.0/PKG-INFO +0 -178
  295. plot_io-0.8.0/README.md +0 -162
  296. plot_io-0.8.0/examples/bars.py +0 -21
  297. plot_io-0.8.0/examples/density.py +0 -23
  298. plot_io-0.8.0/examples/distributions.py +0 -24
  299. plot_io-0.8.0/examples/facets.py +0 -19
  300. plot_io-0.8.0/examples/grids2d.py +0 -23
  301. plot_io-0.8.0/plot_io/__init__.py +0 -55
  302. plot_io-0.8.0/plot_io/_backend.py +0 -46
  303. plot_io-0.8.0/plot_io/_native/bin/linux-aarch64.so +0 -0
  304. plot_io-0.8.0/plot_io/_native/bin/linux-x86_64.so +0 -0
  305. plot_io-0.8.0/plot_io/_native/bin/macos-arm64.dylib +0 -0
  306. plot_io-0.8.0/plot_io/_native/bin/windows-arm64.dll +0 -0
  307. plot_io-0.8.0/plot_io/_native/bin/windows-x86_64.dll +0 -0
  308. plot_io-0.8.0/plot_io/color/__init__.py +0 -4
  309. plot_io-0.8.0/plot_io/color/maps.py +0 -358
  310. plot_io-0.8.0/plot_io/color/palettes.py +0 -206
  311. plot_io-0.8.0/plot_io/color/values.py +0 -278
  312. plot_io-0.8.0/plot_io/decorations.py +0 -521
  313. plot_io-0.8.0/plot_io/genome/__init__.py +0 -11
  314. plot_io-0.8.0/plot_io/genome/layout.py +0 -136
  315. plot_io-0.8.0/plot_io/genome/scale.py +0 -137
  316. plot_io-0.8.0/plot_io/genome/tracks.py +0 -1241
  317. plot_io-0.8.0/plot_io/labels.py +0 -77
  318. plot_io-0.8.0/plot_io/layers/base.py +0 -426
  319. plot_io-0.8.0/plot_io/layers/pipeline.py +0 -91
  320. plot_io-0.8.0/plot_io/layers/positions.py +0 -243
  321. plot_io-0.8.0/plot_io/layers/stats.py +0 -596
  322. plot_io-0.8.0/plot_io/layout.py +0 -1925
  323. plot_io-0.8.0/plot_io/presets/_util.py +0 -301
  324. plot_io-0.8.0/plot_io/presets/area.py +0 -180
  325. plot_io-0.8.0/plot_io/presets/box.py +0 -362
  326. plot_io-0.8.0/plot_io/presets/ecdf.py +0 -93
  327. plot_io-0.8.0/plot_io/presets/errorbar.py +0 -119
  328. plot_io-0.8.0/plot_io/presets/errors.py +0 -159
  329. plot_io-0.8.0/plot_io/presets/fill.py +0 -94
  330. plot_io-0.8.0/plot_io/presets/hist.py +0 -372
  331. plot_io-0.8.0/plot_io/presets/kde.py +0 -176
  332. plot_io-0.8.0/plot_io/presets/line.py +0 -154
  333. plot_io-0.8.0/plot_io/presets/regression.py +0 -120
  334. plot_io-0.8.0/plot_io/presets/scatter.py +0 -125
  335. plot_io-0.8.0/plot_io/presets/stem.py +0 -96
  336. plot_io-0.8.0/plot_io/presets/violin.py +0 -308
  337. plot_io-0.8.0/plot_io/spec.py +0 -204
  338. plot_io-0.8.0/plot_io/styles/library.py +0 -761
  339. plot_io-0.8.0/tests/golden.json +0 -191
  340. plot_io-0.8.0/tests/stats_reference.json +0 -839
  341. plot_io-0.8.0/tests/test_api.py +0 -129
  342. plot_io-0.8.0/tests/test_bars.py +0 -276
  343. plot_io-0.8.0/tests/test_distributions.py +0 -149
  344. plot_io-0.8.0/tests/test_docs.py +0 -70
  345. plot_io-0.8.0/tests/test_genome.py +0 -851
  346. plot_io-0.8.0/tests/test_genome_fixes.py +0 -231
  347. plot_io-0.8.0/tests/test_golden.py +0 -384
  348. plot_io-0.8.0/tests/test_heatmap.py +0 -70
  349. plot_io-0.8.0/tests/test_layout.py +0 -223
  350. plot_io-0.8.0/tests/test_layout_fixes.py +0 -242
  351. plot_io-0.8.0/tests/test_maps.py +0 -281
  352. plot_io-0.8.0/tests/test_native.py +0 -148
  353. plot_io-0.8.0/tests/test_output.py +0 -263
  354. plot_io-0.8.0/tests/test_output_settings_fixes.py +0 -217
  355. plot_io-0.8.0/tests/test_palettes.py +0 -117
  356. plot_io-0.8.0/tests/test_pie.py +0 -48
  357. plot_io-0.8.0/tests/test_plot_fixes.py +0 -312
  358. plot_io-0.8.0/tests/test_registry.py +0 -56
  359. plot_io-0.8.0/tests/test_series.py +0 -112
  360. plot_io-0.8.0/tests/test_settings.py +0 -240
  361. plot_io-0.8.0/tests/test_simplify.py +0 -101
  362. plot_io-0.8.0/tests/test_stats.py +0 -98
  363. plot_io-0.8.0/tests/test_styles.py +0 -213
  364. plot_io-0.8.0/tests/test_ticks.py +0 -93
  365. {plot_io-0.8.0 → plot_io-0.12.0}/LICENSE +0 -0
  366. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/alloc.c +0 -0
  367. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/math.c +0 -0
  368. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/rt.c +0 -0
  369. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/_native/src/sort.c +0 -0
  370. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/genome/pack.py +0 -0
  371. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/markup.py +0 -0
  372. {plot_io-0.8.0 → plot_io-0.12.0}/plot_io/py.typed +0 -0
  373. {plot_io-0.8.0 → plot_io-0.12.0}/tests/fonts/VarTest.ttf +0 -0
@@ -0,0 +1,215 @@
1
+ Metadata-Version: 2.5
2
+ Name: plot_io
3
+ Version: 0.12.0
4
+ Summary: Plots for PDF, EPS, SVG, PNG, JPEG, JPEG XL and AVIF, drawn with vec_io
5
+ Project-URL: Repository, https://github.com/ajgouhier/plot_io
6
+ Author-email: Arthur Gouhier <ajgouhier@gmail.com>
7
+ License-Expression: BSD-3-Clause
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.11
10
+ Requires-Dist: vec-io<0.8,>=0.7
11
+ Provides-Extra: dev
12
+ Requires-Dist: mypy; extra == 'dev'
13
+ Requires-Dist: ruff; extra == 'dev'
14
+ Requires-Dist: ziglang==0.15.1; extra == 'dev'
15
+ Description-Content-Type: text/markdown
16
+
17
+ # plot_io
18
+
19
+ Plotting library in Python. No dependency other than [vec_io](https://github.com/ajgouhier/vec_io).
20
+
21
+ * **Familiar:** a figure of plots; `scatter`, `line`, `fill`, `box`, `heatmap`, `bar`,
22
+ `hist`, `kde` (1-D and 2-D), `ecdf`, `violin`, `strip`, `swarm`, `area`, `errorbar`, `stem`,
23
+ `regression`, `hist2d`, `hexbin`, `contour`, `pie`, `dots`; reference lines, spans, text and
24
+ annotations; `color`, `marker`, `opacity`, `limits`, `scale`, `legend`.
25
+ * **Statistical helpers:** `qq`, `raincloud`, `volcano`, `ma`, `manhattan`, `dendrogram`
26
+ plot types; significance brackets; point labels placed without overlaps; hierarchical
27
+ clustering (`plt.linkage`, scipy's methods); `plt.joint`, `plt.pairs` and `plt.clustermap`
28
+ figures in one call.
29
+ * **Units:** lengths in px, pt, in, mm, `em`, `%` of the axes or of another setting, data
30
+ units and durations (`width="1.5in"`, `tick_length="0.5em"`, `width="60%"`,
31
+ `cap_length="12h"`); `var()` and `calc()` relate settings (`"calc(var(--gap) * 2)"`).
32
+ * **One way to set things:** keywords at creation or `set(...)` on any object; figure
33
+ settings (font, color maps, line width…) are inherited by plots and series.
34
+ * **Layouts:** an explicit grid of ids with spans, or automatic rows and columns; plots
35
+ sized individually; axis lines (or plot borders) aligned across the figure; margins from
36
+ the real text metrics; shared axes; secondary axes; facets of a table.
37
+ * **Titles, legends and colorbars on any side:** several titles per plot; titles,
38
+ legends and colorbar keys shared by any rectangle of plots, nested as headers;
39
+ `share_legend` for one legend per row, column or figure; markup (`<i>`, `<b>`,
40
+ `<sup>`, …) in any text.
41
+ * **Data:** columns of any table by name (`data=`: dicts, pandas, polars, numpy), one
42
+ series per group (`group=`), numbers given as colors or sizes, point density (scipy's
43
+ `gaussian_kde`, in C) for colors, sizes, opacity and drawing order.
44
+ * **Axes:** linear, log, log2, log10, sqrt, exp, symlog, logit, time and category scales;
45
+ limits such as `"0/max"` or `"q:0.01/q:0.99"`; ticks with shared decimals and ×10ᵏ
46
+ factors, calendar ticks for dates.
47
+ * **Colors:** one system of color maps with kinds (qualitative, sequential, diverging,
48
+ cyclic; `okabe_ito` for color-vision deficiencies), a default map per kind, `center=`
49
+ for data about a value, interpolation in Oklab, colorbars;
50
+ marker sizes by area, equal for every shape.
51
+ * **Styles:** `style="matplotlib"`, `"seaborn"`, `"ggplot2"`, `"altair"`, `"matlab"`,
52
+ `"tufte"` give the look of those libraries; styles are presets of settings, and your
53
+ own build on them (a variant: `{"base": "seaborn", …}`).
54
+ * **Output:** PDF, EPS (transparency flattened), SVG, PNG, JPEG, JPEG XL and AVIF, by the
55
+ file's extension; CMYK, PDF/A and text as outlines are options of the save
56
+ (`color="cmyk"`, `pdf={"a": "2b"}`, `text="paths"`).
57
+ * **Large data:** one million points mapped and drawn in C; `simplify="auto"` drops what
58
+ cannot be seen, `rasterize=` turns a series into an image inside the PDF.
59
+ * **Genome tracks:** `bigwig` signals, `bed` intervals, `genes` and `gtf` gene models,
60
+ `hic` triangles and `links` over a region, and `site_profile` and `site_heatmap` around
61
+ sites, read from gwseq_io's readers (or any object with their methods) without
62
+ depending on gwseq_io.
63
+
64
+ ## Install
65
+
66
+ ```sh
67
+ pip install plot_io
68
+ ```
69
+
70
+ Python 3.11+. Text is shaped (kerned) and its fonts embedded by vec_io; it needs an
71
+ installed outline font, the default family list (`Helvetica, Nimbus Sans, Nimbus Sans L,
72
+ TeX Gyre Heros, FreeSans, Arial, Liberation Sans, Arimo`) taking its first installed family
73
+ ([docs/api.md](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md#1-conventions)). JPEG XL
74
+ and AVIF output need vec_io's optional libjxl and libavif.
75
+
76
+ Wheels hold plot_io's C library prebuilt for Linux (x86_64, aarch64; glibc or musl),
77
+ Windows (x86_64, arm64) and macOS 13+ (arm64). Elsewhere (Intel Macs, other CPUs), pip
78
+ builds it from the sdist with the local C compiler (gcc or clang; on Windows clang or MinGW,
79
+ not MSVC); `pip install --no-binary plot_io plot_io` does so on any platform, and
80
+ `pip install .` from a checkout. With the pinned zig in the environment (`pip install
81
+ --require-hashes -r tools/zig.lock`, then `--no-build-isolation`), the sdist builds the
82
+ release binary itself.
83
+
84
+ ```sh
85
+ python -m plot_io._native verify # the library loads, is the release binary, computes as it should
86
+ ```
87
+
88
+ ## Quick start
89
+
90
+ ```python
91
+ import math
92
+ import random
93
+
94
+ import plot_io as plt
95
+
96
+ rng = random.Random(1)
97
+ x = [rng.uniform(0, 10) for _ in range(100)]
98
+ y = [v + rng.gauss(0, 1) for v in x]
99
+ s = plt.Scatter(x, y, name="data")
100
+ s.plot.x_axis(label="Time (s)")
101
+ s.plot.save("scatter.pdf")
102
+ ```
103
+
104
+ ```python
105
+ t = [i / 10 for i in range(1, 101)]
106
+ v = [math.exp(-k / 4) * (2 + math.sin(3 * k)) for k in t]
107
+ upper, lower = [a * 1.3 for a in v], [a * 0.7 for a in v]
108
+ va, vb = [rng.gauss(0, 1) for _ in range(50)], [rng.gauss(1, 1) for _ in range(50)]
109
+ matrix = [[math.sin(i / 2) * math.cos(j / 3) for j in range(6)] for i in range(4)]
110
+ columns, rows = list("ABCDEF"), ["w", "x", "y", "z"]
111
+ z = [a - b for a, b in zip(x, y)]
112
+
113
+ fig = plt.Figure(layout=[[1, 1, 2], [3, 4, 2]])
114
+ p = fig.plot(1, title="Signal")
115
+ p.line(t, v, name="raw")
116
+ p.fill(t, upper, lower, opacity=0.3)
117
+ p.y_axis(scale="log", label="Power")
118
+ fig.plot(2).box({"a": va, "b": vb})
119
+ h = fig.plot(3).heatmap(matrix, x=columns, y=rows, colorbar=True)
120
+ fig.plot(4).scatter(x, y, c=z)
121
+ fig.save("figure.pdf")
122
+ fig.save("figure.png", dpi="2x") # 192 dpi; a number is dots per inch
123
+ fig.save("figure.eps") # PostScript: transparency flattened
124
+ fig.save("figure.svg")
125
+ data = fig.write("pdf", compression="small") # bytes
126
+ ```
127
+
128
+ ```python
129
+ fig = plt.Figure(style="ggplot2") # or a dict: {"base": "seaborn", "font_size": 9}
130
+ ```
131
+
132
+ ```python
133
+ categories, counts = ["a", "b", "c"], [3, 5, 2]
134
+ p = plt.Plot(width="3in", font_size="9pt", vars={"accent": "#c00"})
135
+ p.x_axis(tick_length="0.5em", minor_tick_length="50%")
136
+ p.bar(categories, counts, width="60%", color="var(--accent)") # a custom variable
137
+ p.x_axis.explain("tick_length") # where a value comes from
138
+ ```
139
+
140
+ ```python
141
+ genes = {"umap_x": x, "umap_y": y}
142
+ df = {"x": x, "y": y, "cluster": [int(a) % 3 for a in x],
143
+ "condition": ["ctrl" if a < 5 else "drug" for a in y],
144
+ "replicate": [i % 2 + 1 for i in range(len(x))]}
145
+ p = plt.Plot()
146
+ p.scatter("umap_x", "umap_y", data=genes, c="density", draw_order="density") # columns
147
+ p.scatter("x", "y", data=df, group="cluster", marker="auto") # one series per group
148
+ fig, panels = plt.facet(df, col="condition", row="replicate") # small multiples
149
+ panels.scatter("x", "y")
150
+ ```
151
+
152
+ ## Documentation
153
+
154
+ * [Tutorial](https://github.com/ajgouhier/plot_io/blob/main/docs/tutorial.md): first steps, from a figure to its file.
155
+ * [Guide](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md): the concepts by topic, with the settings tables.
156
+ * [Examples](https://github.com/ajgouhier/plot_io/blob/main/docs/examples.md): every image of the docs, the scripts that draw them, recipes.
157
+ * [Plot types](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md#plot-types): a page per plot type and figure helper, in
158
+ [docs/plots/](https://github.com/ajgouhier/plot_io/tree/main/docs/plots).
159
+ * [Reference](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md#reference): a page per other class, in
160
+ [docs/reference/](https://github.com/ajgouhier/plot_io/tree/main/docs/reference).
161
+ * [Coming from matplotlib](https://github.com/ajgouhier/plot_io/blob/main/docs/from_matplotlib.md): its calls and names in plot_io.
162
+
163
+ ## Development
164
+
165
+ ```sh
166
+ python tools/check.py # every check, one after the other (--list shows them)
167
+ python tools/check.py --fast # without the slow ones (~25 s)
168
+ python tools/check.py --only suite,ruff,mypy
169
+ python -m unittest discover -s tests -t tests
170
+ python tools/bench.py --check # timings: fails over 1.5 × a target
171
+ python tools/gen_docs.py # regenerate the generated sections and pages of docs/
172
+ python tools/gen_docs.py --images # ... and the images of the plot-type pages and the tutorial
173
+ python tools/visual_check.py --save # render the examples as references
174
+ python tools/visual_check.py # ... and later compare with them (pixels, tolerances)
175
+ PLOT_IO_GOLDEN=update python -m unittest discover -s tests -t tests -p test_golden.py
176
+ python tools/record_stats.py > tests/stats_reference.json # with numpy, scipy, statsmodels
177
+ ```
178
+
179
+ The tests use only their own fonts (`tests/fonts`: VioTest, from vec_io's tests, through
180
+ `VEC_IO_FONT_DIRS`; installed fonts are ignored), so their text is the same on every
181
+ machine. The goldens (`tests/golden.json`) are keyed by meaning: the laid-out geometry of
182
+ each scene (rounded to 1/64 px), its drawing calls and its 96 dpi pixels (the last two
183
+ compared where the fonts match those recorded). Pixels are compared exactly, whatever
184
+ vec_io's version, against `tests/golden/*.png` (in the repository, not in the sdist; else
185
+ against a hash in `golden.json`); a changed scene writes its actual image and a diff to
186
+ `$PLOT_IO_GOLDEN_OUT` (default `<tempdir>/plot_io-golden/`) and names them. A missing
187
+ `golden.json`, or a recorded scene no longer drawn, fails. `PLOT_IO_GOLDEN=update` rewrites
188
+ only the files that changed; `PLOT_IO_GOLDEN=dump:DIR` writes the geometry, the drawing
189
+ calls and the PNG of each scene to `DIR` to see what changed.
190
+
191
+ The tests that read real files with gwseq_io run when it is importable: installed, or a
192
+ built checkout beside this one (`../gwseq_io/crates/gwseq-io-py/python`, added to the path
193
+ by `tests/test_genome.py`; elsewhere, put that directory on `PYTHONPATH`). Otherwise they
194
+ are skipped.
195
+
196
+ `PLOT_IO_NATIVE_LIB=PATH` loads that build of plot_io's C library instead of the one in
197
+ `plot_io/_native/bin/` (a sanitizer build, any other build; see
198
+ `plot_io/_native/README.md`).
199
+
200
+ The statistics kernels and color mapping are in plot_io's own C library, `plio`
201
+ (`plot_io/_native`, built like vec_io's: zig, freestanding, five targets). Building and its
202
+ checks:
203
+
204
+ ```sh
205
+ pip install --require-hashes -r tools/zig.lock # the pinned zig
206
+ python tools/build_native.py # bindings from src/plio_api.h, then all targets (not in git)
207
+ python tools/build_native.py --check # every target rebuilt byte for byte as manifest.json says
208
+ python tools/crosscheck.py --qemu PATH/qemu-aarch64-static # same results on aarch64
209
+ python tools/dist.py # the sdist and one wheel per platform built from it
210
+ ```
211
+
212
+ The binaries are built, not committed: `manifest.json` records each target's hash. In a
213
+ checkout, `pip install -e .` builds the host's binary the way pip does from the sdist.
214
+
215
+ See [plot_io/_native/README.md](plot_io/_native/README.md).
@@ -0,0 +1,199 @@
1
+ # plot_io
2
+
3
+ Plotting library in Python. No dependency other than [vec_io](https://github.com/ajgouhier/vec_io).
4
+
5
+ * **Familiar:** a figure of plots; `scatter`, `line`, `fill`, `box`, `heatmap`, `bar`,
6
+ `hist`, `kde` (1-D and 2-D), `ecdf`, `violin`, `strip`, `swarm`, `area`, `errorbar`, `stem`,
7
+ `regression`, `hist2d`, `hexbin`, `contour`, `pie`, `dots`; reference lines, spans, text and
8
+ annotations; `color`, `marker`, `opacity`, `limits`, `scale`, `legend`.
9
+ * **Statistical helpers:** `qq`, `raincloud`, `volcano`, `ma`, `manhattan`, `dendrogram`
10
+ plot types; significance brackets; point labels placed without overlaps; hierarchical
11
+ clustering (`plt.linkage`, scipy's methods); `plt.joint`, `plt.pairs` and `plt.clustermap`
12
+ figures in one call.
13
+ * **Units:** lengths in px, pt, in, mm, `em`, `%` of the axes or of another setting, data
14
+ units and durations (`width="1.5in"`, `tick_length="0.5em"`, `width="60%"`,
15
+ `cap_length="12h"`); `var()` and `calc()` relate settings (`"calc(var(--gap) * 2)"`).
16
+ * **One way to set things:** keywords at creation or `set(...)` on any object; figure
17
+ settings (font, color maps, line width…) are inherited by plots and series.
18
+ * **Layouts:** an explicit grid of ids with spans, or automatic rows and columns; plots
19
+ sized individually; axis lines (or plot borders) aligned across the figure; margins from
20
+ the real text metrics; shared axes; secondary axes; facets of a table.
21
+ * **Titles, legends and colorbars on any side:** several titles per plot; titles,
22
+ legends and colorbar keys shared by any rectangle of plots, nested as headers;
23
+ `share_legend` for one legend per row, column or figure; markup (`<i>`, `<b>`,
24
+ `<sup>`, …) in any text.
25
+ * **Data:** columns of any table by name (`data=`: dicts, pandas, polars, numpy), one
26
+ series per group (`group=`), numbers given as colors or sizes, point density (scipy's
27
+ `gaussian_kde`, in C) for colors, sizes, opacity and drawing order.
28
+ * **Axes:** linear, log, log2, log10, sqrt, exp, symlog, logit, time and category scales;
29
+ limits such as `"0/max"` or `"q:0.01/q:0.99"`; ticks with shared decimals and ×10ᵏ
30
+ factors, calendar ticks for dates.
31
+ * **Colors:** one system of color maps with kinds (qualitative, sequential, diverging,
32
+ cyclic; `okabe_ito` for color-vision deficiencies), a default map per kind, `center=`
33
+ for data about a value, interpolation in Oklab, colorbars;
34
+ marker sizes by area, equal for every shape.
35
+ * **Styles:** `style="matplotlib"`, `"seaborn"`, `"ggplot2"`, `"altair"`, `"matlab"`,
36
+ `"tufte"` give the look of those libraries; styles are presets of settings, and your
37
+ own build on them (a variant: `{"base": "seaborn", …}`).
38
+ * **Output:** PDF, EPS (transparency flattened), SVG, PNG, JPEG, JPEG XL and AVIF, by the
39
+ file's extension; CMYK, PDF/A and text as outlines are options of the save
40
+ (`color="cmyk"`, `pdf={"a": "2b"}`, `text="paths"`).
41
+ * **Large data:** one million points mapped and drawn in C; `simplify="auto"` drops what
42
+ cannot be seen, `rasterize=` turns a series into an image inside the PDF.
43
+ * **Genome tracks:** `bigwig` signals, `bed` intervals, `genes` and `gtf` gene models,
44
+ `hic` triangles and `links` over a region, and `site_profile` and `site_heatmap` around
45
+ sites, read from gwseq_io's readers (or any object with their methods) without
46
+ depending on gwseq_io.
47
+
48
+ ## Install
49
+
50
+ ```sh
51
+ pip install plot_io
52
+ ```
53
+
54
+ Python 3.11+. Text is shaped (kerned) and its fonts embedded by vec_io; it needs an
55
+ installed outline font, the default family list (`Helvetica, Nimbus Sans, Nimbus Sans L,
56
+ TeX Gyre Heros, FreeSans, Arial, Liberation Sans, Arimo`) taking its first installed family
57
+ ([docs/api.md](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md#1-conventions)). JPEG XL
58
+ and AVIF output need vec_io's optional libjxl and libavif.
59
+
60
+ Wheels hold plot_io's C library prebuilt for Linux (x86_64, aarch64; glibc or musl),
61
+ Windows (x86_64, arm64) and macOS 13+ (arm64). Elsewhere (Intel Macs, other CPUs), pip
62
+ builds it from the sdist with the local C compiler (gcc or clang; on Windows clang or MinGW,
63
+ not MSVC); `pip install --no-binary plot_io plot_io` does so on any platform, and
64
+ `pip install .` from a checkout. With the pinned zig in the environment (`pip install
65
+ --require-hashes -r tools/zig.lock`, then `--no-build-isolation`), the sdist builds the
66
+ release binary itself.
67
+
68
+ ```sh
69
+ python -m plot_io._native verify # the library loads, is the release binary, computes as it should
70
+ ```
71
+
72
+ ## Quick start
73
+
74
+ ```python
75
+ import math
76
+ import random
77
+
78
+ import plot_io as plt
79
+
80
+ rng = random.Random(1)
81
+ x = [rng.uniform(0, 10) for _ in range(100)]
82
+ y = [v + rng.gauss(0, 1) for v in x]
83
+ s = plt.Scatter(x, y, name="data")
84
+ s.plot.x_axis(label="Time (s)")
85
+ s.plot.save("scatter.pdf")
86
+ ```
87
+
88
+ ```python
89
+ t = [i / 10 for i in range(1, 101)]
90
+ v = [math.exp(-k / 4) * (2 + math.sin(3 * k)) for k in t]
91
+ upper, lower = [a * 1.3 for a in v], [a * 0.7 for a in v]
92
+ va, vb = [rng.gauss(0, 1) for _ in range(50)], [rng.gauss(1, 1) for _ in range(50)]
93
+ matrix = [[math.sin(i / 2) * math.cos(j / 3) for j in range(6)] for i in range(4)]
94
+ columns, rows = list("ABCDEF"), ["w", "x", "y", "z"]
95
+ z = [a - b for a, b in zip(x, y)]
96
+
97
+ fig = plt.Figure(layout=[[1, 1, 2], [3, 4, 2]])
98
+ p = fig.plot(1, title="Signal")
99
+ p.line(t, v, name="raw")
100
+ p.fill(t, upper, lower, opacity=0.3)
101
+ p.y_axis(scale="log", label="Power")
102
+ fig.plot(2).box({"a": va, "b": vb})
103
+ h = fig.plot(3).heatmap(matrix, x=columns, y=rows, colorbar=True)
104
+ fig.plot(4).scatter(x, y, c=z)
105
+ fig.save("figure.pdf")
106
+ fig.save("figure.png", dpi="2x") # 192 dpi; a number is dots per inch
107
+ fig.save("figure.eps") # PostScript: transparency flattened
108
+ fig.save("figure.svg")
109
+ data = fig.write("pdf", compression="small") # bytes
110
+ ```
111
+
112
+ ```python
113
+ fig = plt.Figure(style="ggplot2") # or a dict: {"base": "seaborn", "font_size": 9}
114
+ ```
115
+
116
+ ```python
117
+ categories, counts = ["a", "b", "c"], [3, 5, 2]
118
+ p = plt.Plot(width="3in", font_size="9pt", vars={"accent": "#c00"})
119
+ p.x_axis(tick_length="0.5em", minor_tick_length="50%")
120
+ p.bar(categories, counts, width="60%", color="var(--accent)") # a custom variable
121
+ p.x_axis.explain("tick_length") # where a value comes from
122
+ ```
123
+
124
+ ```python
125
+ genes = {"umap_x": x, "umap_y": y}
126
+ df = {"x": x, "y": y, "cluster": [int(a) % 3 for a in x],
127
+ "condition": ["ctrl" if a < 5 else "drug" for a in y],
128
+ "replicate": [i % 2 + 1 for i in range(len(x))]}
129
+ p = plt.Plot()
130
+ p.scatter("umap_x", "umap_y", data=genes, c="density", draw_order="density") # columns
131
+ p.scatter("x", "y", data=df, group="cluster", marker="auto") # one series per group
132
+ fig, panels = plt.facet(df, col="condition", row="replicate") # small multiples
133
+ panels.scatter("x", "y")
134
+ ```
135
+
136
+ ## Documentation
137
+
138
+ * [Tutorial](https://github.com/ajgouhier/plot_io/blob/main/docs/tutorial.md): first steps, from a figure to its file.
139
+ * [Guide](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md): the concepts by topic, with the settings tables.
140
+ * [Examples](https://github.com/ajgouhier/plot_io/blob/main/docs/examples.md): every image of the docs, the scripts that draw them, recipes.
141
+ * [Plot types](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md#plot-types): a page per plot type and figure helper, in
142
+ [docs/plots/](https://github.com/ajgouhier/plot_io/tree/main/docs/plots).
143
+ * [Reference](https://github.com/ajgouhier/plot_io/blob/main/docs/api.md#reference): a page per other class, in
144
+ [docs/reference/](https://github.com/ajgouhier/plot_io/tree/main/docs/reference).
145
+ * [Coming from matplotlib](https://github.com/ajgouhier/plot_io/blob/main/docs/from_matplotlib.md): its calls and names in plot_io.
146
+
147
+ ## Development
148
+
149
+ ```sh
150
+ python tools/check.py # every check, one after the other (--list shows them)
151
+ python tools/check.py --fast # without the slow ones (~25 s)
152
+ python tools/check.py --only suite,ruff,mypy
153
+ python -m unittest discover -s tests -t tests
154
+ python tools/bench.py --check # timings: fails over 1.5 × a target
155
+ python tools/gen_docs.py # regenerate the generated sections and pages of docs/
156
+ python tools/gen_docs.py --images # ... and the images of the plot-type pages and the tutorial
157
+ python tools/visual_check.py --save # render the examples as references
158
+ python tools/visual_check.py # ... and later compare with them (pixels, tolerances)
159
+ PLOT_IO_GOLDEN=update python -m unittest discover -s tests -t tests -p test_golden.py
160
+ python tools/record_stats.py > tests/stats_reference.json # with numpy, scipy, statsmodels
161
+ ```
162
+
163
+ The tests use only their own fonts (`tests/fonts`: VioTest, from vec_io's tests, through
164
+ `VEC_IO_FONT_DIRS`; installed fonts are ignored), so their text is the same on every
165
+ machine. The goldens (`tests/golden.json`) are keyed by meaning: the laid-out geometry of
166
+ each scene (rounded to 1/64 px), its drawing calls and its 96 dpi pixels (the last two
167
+ compared where the fonts match those recorded). Pixels are compared exactly, whatever
168
+ vec_io's version, against `tests/golden/*.png` (in the repository, not in the sdist; else
169
+ against a hash in `golden.json`); a changed scene writes its actual image and a diff to
170
+ `$PLOT_IO_GOLDEN_OUT` (default `<tempdir>/plot_io-golden/`) and names them. A missing
171
+ `golden.json`, or a recorded scene no longer drawn, fails. `PLOT_IO_GOLDEN=update` rewrites
172
+ only the files that changed; `PLOT_IO_GOLDEN=dump:DIR` writes the geometry, the drawing
173
+ calls and the PNG of each scene to `DIR` to see what changed.
174
+
175
+ The tests that read real files with gwseq_io run when it is importable: installed, or a
176
+ built checkout beside this one (`../gwseq_io/crates/gwseq-io-py/python`, added to the path
177
+ by `tests/test_genome.py`; elsewhere, put that directory on `PYTHONPATH`). Otherwise they
178
+ are skipped.
179
+
180
+ `PLOT_IO_NATIVE_LIB=PATH` loads that build of plot_io's C library instead of the one in
181
+ `plot_io/_native/bin/` (a sanitizer build, any other build; see
182
+ `plot_io/_native/README.md`).
183
+
184
+ The statistics kernels and color mapping are in plot_io's own C library, `plio`
185
+ (`plot_io/_native`, built like vec_io's: zig, freestanding, five targets). Building and its
186
+ checks:
187
+
188
+ ```sh
189
+ pip install --require-hashes -r tools/zig.lock # the pinned zig
190
+ python tools/build_native.py # bindings from src/plio_api.h, then all targets (not in git)
191
+ python tools/build_native.py --check # every target rebuilt byte for byte as manifest.json says
192
+ python tools/crosscheck.py --qemu PATH/qemu-aarch64-static # same results on aarch64
193
+ python tools/dist.py # the sdist and one wheel per platform built from it
194
+ ```
195
+
196
+ The binaries are built, not committed: `manifest.json` records each target's hash. In a
197
+ checkout, `pip install -e .` builds the host's binary the way pip does from the sdist.
198
+
199
+ See [plot_io/_native/README.md](plot_io/_native/README.md).