seraplot 2.3.84__tar.gz → 2.3.86__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 (417) hide show
  1. {seraplot-2.3.84 → seraplot-2.3.86}/Cargo.lock +1 -1
  2. {seraplot-2.3.84 → seraplot-2.3.86}/Cargo.toml +1 -1
  3. {seraplot-2.3.84 → seraplot-2.3.86}/PKG-INFO +1 -1
  4. {seraplot-2.3.84 → seraplot-2.3.86}/pyproject.toml +1 -1
  5. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/commands/charts.rs +150 -0
  6. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/commands/registry.rs +6 -0
  7. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/registry_macro.rs +157 -0
  8. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/SUMMARY.md +11 -0
  9. seraplot-2.3.86/src/docs/config/a11y.md +41 -0
  10. seraplot-2.3.86/src/docs/config/automl.md +69 -0
  11. seraplot-2.3.86/src/docs/config/csp.md +33 -0
  12. seraplot-2.3.86/src/docs/config/diff.md +53 -0
  13. seraplot-2.3.86/src/docs/config/downsample.md +63 -0
  14. seraplot-2.3.86/src/docs/config/drift.md +77 -0
  15. seraplot-2.3.86/src/docs/config/export.md +231 -0
  16. seraplot-2.3.86/src/docs/config/facet.md +67 -0
  17. seraplot-2.3.86/src/docs/config/ml-persistence.md +292 -0
  18. seraplot-2.3.86/src/docs/config/pickle.md +43 -0
  19. seraplot-2.3.86/src/docs/config/streaming.md +235 -0
  20. {seraplot-2.3.84 → seraplot-2.3.86}/src/lib.rs +114 -0
  21. {seraplot-2.3.84 → seraplot-2.3.86}/.gitignore +0 -0
  22. {seraplot-2.3.84 → seraplot-2.3.86}/05--Diabetes_SeraPlot.ipynb +0 -0
  23. {seraplot-2.3.84 → seraplot-2.3.86}/07--OpenFoodFacts_SeraPlot_Benchmark.ipynb +0 -0
  24. {seraplot-2.3.84 → seraplot-2.3.86}/README.md +0 -0
  25. {seraplot-2.3.84 → seraplot-2.3.86}/TEST_1M_Battle.ipynb +0 -0
  26. {seraplot-2.3.84 → seraplot-2.3.86}/bench_all.py +0 -0
  27. {seraplot-2.3.84 → seraplot-2.3.86}/bench_bigdata.py +0 -0
  28. {seraplot-2.3.84 → seraplot-2.3.86}/bench_full.py +0 -0
  29. {seraplot-2.3.84 → seraplot-2.3.86}/bench_issues.json +0 -0
  30. {seraplot-2.3.84 → seraplot-2.3.86}/bench_knn_sgd.py +0 -0
  31. {seraplot-2.3.84 → seraplot-2.3.86}/bench_perf.py +0 -0
  32. {seraplot-2.3.84 → seraplot-2.3.86}/bench_quick.py +0 -0
  33. {seraplot-2.3.84 → seraplot-2.3.86}/bench_quick2.py +0 -0
  34. {seraplot-2.3.84 → seraplot-2.3.86}/bench_scale.py +0 -0
  35. {seraplot-2.3.84 → seraplot-2.3.86}/bench_seraplot.py +0 -0
  36. {seraplot-2.3.84 → seraplot-2.3.86}/bench_sklearn.py +0 -0
  37. {seraplot-2.3.84 → seraplot-2.3.86}/bench_svc.py +0 -0
  38. {seraplot-2.3.84 → seraplot-2.3.86}/bench_svc2.py +0 -0
  39. {seraplot-2.3.84 → seraplot-2.3.86}/bench_test.py +0 -0
  40. {seraplot-2.3.84 → seraplot-2.3.86}/benchmark_gridsearch.py +0 -0
  41. {seraplot-2.3.84 → seraplot-2.3.86}/benchmark_gridsearch2.py +0 -0
  42. {seraplot-2.3.84 → seraplot-2.3.86}/benchmark_kmeans_heavy.ipynb +0 -0
  43. {seraplot-2.3.84 → seraplot-2.3.86}/benchmark_kmeans_openfoodfacts.ipynb +0 -0
  44. {seraplot-2.3.84 → seraplot-2.3.86}/benchmark_ml.ipynb +0 -0
  45. {seraplot-2.3.84 → seraplot-2.3.86}/benchmark_ml_openfoodfacts.ipynb +0 -0
  46. {seraplot-2.3.84 → seraplot-2.3.86}/benchmark_ml_out.ipynb +0 -0
  47. {seraplot-2.3.84 → seraplot-2.3.86}/build.log +0 -0
  48. {seraplot-2.3.84 → seraplot-2.3.86}/gen_bench_slides.py +0 -0
  49. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/1.png +0 -0
  50. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/2.png +0 -0
  51. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/3.png +0 -0
  52. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/4.png +0 -0
  53. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/5.png +0 -0
  54. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/6.png +0 -0
  55. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/7.png +0 -0
  56. {seraplot-2.3.84 → seraplot-2.3.86}/images/2d/8.png +0 -0
  57. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/1.png +0 -0
  58. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/2.png +0 -0
  59. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/3.png +0 -0
  60. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/4.png +0 -0
  61. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/5.png +0 -0
  62. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/6.png +0 -0
  63. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/7.png +0 -0
  64. {seraplot-2.3.84 → seraplot-2.3.86}/images/3d/8.png +0 -0
  65. {seraplot-2.3.84 → seraplot-2.3.86}/images/README.md +0 -0
  66. {seraplot-2.3.84 → seraplot-2.3.86}/images/benchmark/1.png +0 -0
  67. {seraplot-2.3.84 → seraplot-2.3.86}/images/benchmark/2.png +0 -0
  68. {seraplot-2.3.84 → seraplot-2.3.86}/images/benchmark/3.png +0 -0
  69. {seraplot-2.3.84 → seraplot-2.3.86}/images/logo.png +0 -0
  70. {seraplot-2.3.84 → seraplot-2.3.86}/kmeans_test.html +0 -0
  71. {seraplot-2.3.84 → seraplot-2.3.86}/publish_2378.log +0 -0
  72. {seraplot-2.3.84 → seraplot-2.3.86}/publish_log.txt +0 -0
  73. {seraplot-2.3.84 → seraplot-2.3.86}/python/seraplot/__init__.py +0 -0
  74. {seraplot-2.3.84 → seraplot-2.3.86}/python/seraplot/matplotlib.py +0 -0
  75. {seraplot-2.3.84 → seraplot-2.3.86}/python/seraplot/seraplot.cp311-win_amd64.pyd.old +0 -0
  76. {seraplot-2.3.84 → seraplot-2.3.86}/results_seraplot.json +0 -0
  77. {seraplot-2.3.84 → seraplot-2.3.86}/results_sklearn.json +0 -0
  78. {seraplot-2.3.84 → seraplot-2.3.86}/src/.github/workflows/mdbook.yml +0 -0
  79. {seraplot-2.3.84 → seraplot-2.3.86}/src/README.md +0 -0
  80. {seraplot-2.3.84 → seraplot-2.3.86}/src/asset/SVG World Map with labels.svg +0 -0
  81. {seraplot-2.3.84 → seraplot-2.3.86}/src/asset/logo.png +0 -0
  82. {seraplot-2.3.84 → seraplot-2.3.86}/src/asset/world.svg +0 -0
  83. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/builder_template.rs +0 -0
  84. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/chart_types.rs +0 -0
  85. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/commands/docs.rs +0 -0
  86. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/commands/ml.rs +0 -0
  87. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/commands/mod.rs +0 -0
  88. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/commands/native.rs +0 -0
  89. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/export_builder.rs +0 -0
  90. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/fast_export_c.rs +0 -0
  91. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/fast_render.rs +0 -0
  92. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/memory_pool.rs +0 -0
  93. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/mod.rs +0 -0
  94. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/unified_builder.rs +0 -0
  95. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/unified_config.rs +0 -0
  96. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/arena_alloc.rs +0 -0
  97. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/bitset.rs +0 -0
  98. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/compact_state.rs +0 -0
  99. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/data_processor.rs +0 -0
  100. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/image_processor.rs +0 -0
  101. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/lazy_builders.rs +0 -0
  102. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/memory_pool.rs +0 -0
  103. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/mod.rs +0 -0
  104. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/simd_ops.rs +0 -0
  105. {seraplot-2.3.84 → seraplot-2.3.86}/src/bindings/utils/state_export.rs +0 -0
  106. {seraplot-2.3.84 → seraplot-2.3.86}/src/book.toml +0 -0
  107. {seraplot-2.3.84 → seraplot-2.3.86}/src/core/builders.rs +0 -0
  108. {seraplot-2.3.84 → seraplot-2.3.86}/src/core/math.rs +0 -0
  109. {seraplot-2.3.84 → seraplot-2.3.86}/src/core/mod.rs +0 -0
  110. {seraplot-2.3.84 → seraplot-2.3.86}/src/data/conversion.rs +0 -0
  111. {seraplot-2.3.84 → seraplot-2.3.86}/src/data/index.rs +0 -0
  112. {seraplot-2.3.84 → seraplot-2.3.86}/src/data/loader.rs +0 -0
  113. {seraplot-2.3.84 → seraplot-2.3.86}/src/data/mod.rs +0 -0
  114. {seraplot-2.3.84 → seraplot-2.3.86}/src/data/processor.rs +0 -0
  115. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/api/index.md +0 -0
  116. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/area.md +0 -0
  117. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/bar.md +0 -0
  118. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/boxplot.md +0 -0
  119. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/bubble.md +0 -0
  120. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/bullet.md +0 -0
  121. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/candlestick.md +0 -0
  122. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/donut.md +0 -0
  123. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/dumbbell.md +0 -0
  124. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/funnel.md +0 -0
  125. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/gauge.md +0 -0
  126. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/grid.md +0 -0
  127. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/grouped-bar.md +0 -0
  128. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/hbar.md +0 -0
  129. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/heatmap.md +0 -0
  130. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/histogram-overlay.md +0 -0
  131. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/histogram.md +0 -0
  132. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/index.md +0 -0
  133. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/kde.md +0 -0
  134. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/line.md +0 -0
  135. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/lollipop.md +0 -0
  136. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/multiline.md +0 -0
  137. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/parallel.md +0 -0
  138. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/pie.md +0 -0
  139. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/radar.md +0 -0
  140. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/ridgeline.md +0 -0
  141. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/scatter.md +0 -0
  142. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/slideshow.md +0 -0
  143. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/slope.md +0 -0
  144. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/stacked-bar.md +0 -0
  145. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/sunburst.md +0 -0
  146. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/treemap.md +0 -0
  147. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/violin.md +0 -0
  148. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/waterfall.md +0 -0
  149. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/2d/wordcloud.md +0 -0
  150. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/bar3d.md +0 -0
  151. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/bubble3d.md +0 -0
  152. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/candlestick3d.md +0 -0
  153. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/dumbbell3d.md +0 -0
  154. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/funnel3d.md +0 -0
  155. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/globe3d.md +0 -0
  156. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/heatmap3d.md +0 -0
  157. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/index.md +0 -0
  158. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/kde3d.md +0 -0
  159. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/line3d.md +0 -0
  160. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/lollipop3d.md +0 -0
  161. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/pie3d.md +0 -0
  162. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/radar3d.md +0 -0
  163. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/ridgeline3d.md +0 -0
  164. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/scatter3d.md +0 -0
  165. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/stacked-bar3d.md +0 -0
  166. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/sunburst3d.md +0 -0
  167. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/3d/violin3d.md +0 -0
  168. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/map/bubble-map.md +0 -0
  169. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/map/choropleth.md +0 -0
  170. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/charts/map/index.md +0 -0
  171. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/config/auto-display.md +0 -0
  172. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/config/background.md +0 -0
  173. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/config/hover.md +0 -0
  174. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/config/palette.md +0 -0
  175. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/getting-started/chart-methods.md +0 -0
  176. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/getting-started/chart-object.md +0 -0
  177. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/getting-started/installation.md +0 -0
  178. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/getting-started/quickstart.md +0 -0
  179. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/introduction.md +0 -0
  180. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/adaboost.md +0 -0
  181. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/bayes-index.md +0 -0
  182. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/clustering-index.md +0 -0
  183. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/dbscan-class.md +0 -0
  184. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/dbscan.md +0 -0
  185. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/dbscan3d.md +0 -0
  186. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/decision-tree.md +0 -0
  187. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/decomposition-index.md +0 -0
  188. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/decomposition.md +0 -0
  189. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/elastic-net.md +0 -0
  190. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/evaluation-index.md +0 -0
  191. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/gradient-boosting.md +0 -0
  192. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/grid-search.md +0 -0
  193. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/index.md +0 -0
  194. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/kmeans-class.md +0 -0
  195. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/kmeans.md +0 -0
  196. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/knn.md +0 -0
  197. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/lasso.md +0 -0
  198. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/linear-index.md +0 -0
  199. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/linear-regression.md +0 -0
  200. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/logistic-regression.md +0 -0
  201. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/metrics.md +0 -0
  202. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/naive-bayes.md +0 -0
  203. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/neighbors-index.md +0 -0
  204. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/preprocessing-index.md +0 -0
  205. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/preprocessing.md +0 -0
  206. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/random-forest.md +0 -0
  207. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/ridge.md +0 -0
  208. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/selection-index.md +0 -0
  209. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/sgd.md +0 -0
  210. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/svm-index.md +0 -0
  211. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/svm.md +0 -0
  212. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/train-test-split.md +0 -0
  213. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/ml/tree-index.md +0 -0
  214. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/area.html +0 -0
  215. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bar.html +0 -0
  216. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bar3d.html +0 -0
  217. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bench-matplotlib.html +0 -0
  218. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bench-plotly.html +0 -0
  219. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bench-seraplot.html +0 -0
  220. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/boxplot.html +0 -0
  221. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bubble-map.html +0 -0
  222. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bubble.html +0 -0
  223. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bubble3d.html +0 -0
  224. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/bullet.html +0 -0
  225. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/candlestick.html +0 -0
  226. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/candlestick3d.html +0 -0
  227. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/choropleth.html +0 -0
  228. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/dbscan-class.html +0 -0
  229. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/dbscan.html +0 -0
  230. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/dbscan3d.html +0 -0
  231. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/donut.html +0 -0
  232. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/dumbbell.html +0 -0
  233. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/dumbbell3d.html +0 -0
  234. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/funnel.html +0 -0
  235. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/funnel3d.html +0 -0
  236. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/gauge.html +0 -0
  237. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/globe3d.html +0 -0
  238. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/grid.html +0 -0
  239. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/grouped-bar.html +0 -0
  240. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/hbar.html +0 -0
  241. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/heatmap.html +0 -0
  242. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/heatmap3d.html +0 -0
  243. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/histogram-overlay.html +0 -0
  244. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/histogram.html +0 -0
  245. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/kde.html +0 -0
  246. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/kde3d.html +0 -0
  247. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/line.html +0 -0
  248. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/line3d.html +0 -0
  249. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/lollipop.html +0 -0
  250. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/lollipop3d.html +0 -0
  251. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/multiline.html +0 -0
  252. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/parallel.html +0 -0
  253. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/pie.html +0 -0
  254. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/pie3d.html +0 -0
  255. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/radar.html +0 -0
  256. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/radar3d.html +0 -0
  257. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/ridgeline.html +0 -0
  258. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/ridgeline3d.html +0 -0
  259. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/scatter.html +0 -0
  260. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/scatter3d.html +0 -0
  261. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/slideshow.html +0 -0
  262. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/slope.html +0 -0
  263. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/stacked-bar.html +0 -0
  264. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/stacked-bar3d.html +0 -0
  265. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/sunburst.html +0 -0
  266. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/sunburst3d.html +0 -0
  267. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/treemap.html +0 -0
  268. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/violin.html +0 -0
  269. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/violin3d.html +0 -0
  270. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/waterfall.html +0 -0
  271. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/previews/wordcloud.html +0 -0
  272. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/theme/custom.css +0 -0
  273. {seraplot-2.3.84 → seraplot-2.3.86}/src/docs/theme/lang-switcher.js +0 -0
  274. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/assets.rs +0 -0
  275. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/fast_builders.rs +0 -0
  276. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/fast_exporter.rs +0 -0
  277. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/hover.rs +0 -0
  278. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/html_export.rs +0 -0
  279. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/html_template.rs +0 -0
  280. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/js_3d.rs +0 -0
  281. {seraplot-2.3.84 → seraplot-2.3.86}/src/html/mod.rs +0 -0
  282. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/cache.rs +0 -0
  283. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/decomposition/mod.rs +0 -0
  284. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/decomposition/pca.rs +0 -0
  285. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linalg.rs +0 -0
  286. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linear/elastic_net.rs +0 -0
  287. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linear/lasso.rs +0 -0
  288. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linear/logistic.rs +0 -0
  289. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linear/mod.rs +0 -0
  290. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linear/ols.rs +0 -0
  291. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linear/ridge.rs +0 -0
  292. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/linear/sgd.rs +0 -0
  293. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/metrics/classification.rs +0 -0
  294. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/metrics/mod.rs +0 -0
  295. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/metrics/regression.rs +0 -0
  296. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/mod.rs +0 -0
  297. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/model_selection/cross_val.rs +0 -0
  298. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/model_selection/grid_search.rs +0 -0
  299. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/model_selection/mod.rs +0 -0
  300. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/model_selection/split.rs +0 -0
  301. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/naive_bayes/bernoulli.rs +0 -0
  302. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/naive_bayes/gaussian.rs +0 -0
  303. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/naive_bayes/mod.rs +0 -0
  304. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/naive_bayes/multinomial.rs +0 -0
  305. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/neighbors/knn.rs +0 -0
  306. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/neighbors/mod.rs +0 -0
  307. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/preprocessing/encoders.rs +0 -0
  308. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/preprocessing/mod.rs +0 -0
  309. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/preprocessing/scalers.rs +0 -0
  310. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/svm/mod.rs +0 -0
  311. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/svm/svm.rs +0 -0
  312. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/tree/adaboost.rs +0 -0
  313. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/tree/decision_tree.rs +0 -0
  314. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/tree/decision_tree_backup.rs +0 -0
  315. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/tree/gradient_boosting.rs +0 -0
  316. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/tree/mod.rs +0 -0
  317. {seraplot-2.3.84 → seraplot-2.3.86}/src/ml/tree/random_forest.rs +0 -0
  318. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/camera.rs +0 -0
  319. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/canvas.rs +0 -0
  320. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/containers_3d.rs +0 -0
  321. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/controller/chart_controller.rs +0 -0
  322. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/controller/mod.rs +0 -0
  323. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/controller/plot_3d_controller.rs +0 -0
  324. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/_3d/bar_3d.rs +0 -0
  325. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/_3d/line_3d.rs +0 -0
  326. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/_3d/mod.rs +0 -0
  327. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/_3d/plot_3d_types.rs +0 -0
  328. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/_3d/scatter_3d.rs +0 -0
  329. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/bar.rs +0 -0
  330. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/chart.rs +0 -0
  331. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/kmeans.rs +0 -0
  332. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/line.rs +0 -0
  333. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/mod.rs +0 -0
  334. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/scatter.rs +0 -0
  335. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/default/svg.rs +0 -0
  336. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/generic.rs +0 -0
  337. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/_3d/globe.rs +0 -0
  338. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/_3d/globe_html.rs +0 -0
  339. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/_3d/globe_types.rs +0 -0
  340. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/_3d/mod.rs +0 -0
  341. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/bubble_map.rs +0 -0
  342. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/chart.rs +0 -0
  343. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/choropleth.rs +0 -0
  344. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/mod.rs +0 -0
  345. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/svg_parser.rs +0 -0
  346. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/map/world_data.rs +0 -0
  347. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/mod.rs +0 -0
  348. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/projection.rs +0 -0
  349. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/renderers.rs +0 -0
  350. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/scale_renderer.rs +0 -0
  351. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/seaborn/_3d/mod.rs +0 -0
  352. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/seaborn/_3d/plot_3d_types.rs +0 -0
  353. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/seaborn/chart.rs +0 -0
  354. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/seaborn/mod.rs +0 -0
  355. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/candlestick3d.rs +0 -0
  356. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/dumbbell3d.rs +0 -0
  357. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/funnel3d.rs +0 -0
  358. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/heatmap3d.rs +0 -0
  359. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/kde3d.rs +0 -0
  360. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/lollipop3d.rs +0 -0
  361. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/mod.rs +0 -0
  362. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/pie3d.rs +0 -0
  363. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/plot_3d_types.rs +0 -0
  364. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/radar3d.rs +0 -0
  365. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/ridgeline3d.rs +0 -0
  366. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/stacked_bar3d.rs +0 -0
  367. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/sunburst3d.rs +0 -0
  368. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/_3d/violin3d.rs +0 -0
  369. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/area.rs +0 -0
  370. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/boxplot.rs +0 -0
  371. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/bubble.rs +0 -0
  372. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/bullet.rs +0 -0
  373. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/candlestick.rs +0 -0
  374. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/common.rs +0 -0
  375. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/dumbbell.rs +0 -0
  376. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/funnel.rs +0 -0
  377. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/gauge.rs +0 -0
  378. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/grouped_bar.rs +0 -0
  379. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/heatmap.rs +0 -0
  380. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/histogram.rs +0 -0
  381. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/kde.rs +0 -0
  382. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/lollipop.rs +0 -0
  383. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/mod.rs +0 -0
  384. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/multiline.rs +0 -0
  385. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/parallel.rs +0 -0
  386. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/pie.rs +0 -0
  387. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/radar.rs +0 -0
  388. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/ridgeline.rs +0 -0
  389. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/slope.rs +0 -0
  390. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/sunburst.rs +0 -0
  391. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/treemap.rs +0 -0
  392. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/violin.rs +0 -0
  393. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/waterfall.rs +0 -0
  394. {seraplot-2.3.84 → seraplot-2.3.86}/src/plot/statistical/wordcloud.rs +0 -0
  395. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/cache.rs +0 -0
  396. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/chart.rs +0 -0
  397. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/gui.rs +0 -0
  398. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/hybrid.rs +0 -0
  399. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/manager/button_manager.rs +0 -0
  400. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/manager/mod.rs +0 -0
  401. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/mod.rs +0 -0
  402. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/render/advanced_render.rs +0 -0
  403. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/render/fast_render_gui.rs +0 -0
  404. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/render/mod.rs +0 -0
  405. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/render/pipeline.rs +0 -0
  406. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/render/viewer_3d.rs +0 -0
  407. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/render/wiki_viewer.rs +0 -0
  408. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/utils/image_loader.rs +0 -0
  409. {seraplot-2.3.84 → seraplot-2.3.86}/src/viewer/utils/mod.rs +0 -0
  410. {seraplot-2.3.84 → seraplot-2.3.86}/src/wiki/api.rs +0 -0
  411. {seraplot-2.3.84 → seraplot-2.3.86}/src/wiki/extractor.rs +0 -0
  412. {seraplot-2.3.84 → seraplot-2.3.86}/src/wiki/language.rs +0 -0
  413. {seraplot-2.3.84 → seraplot-2.3.86}/src/wiki/macros.rs +0 -0
  414. {seraplot-2.3.84 → seraplot-2.3.86}/src/wiki/metadata.rs +0 -0
  415. {seraplot-2.3.84 → seraplot-2.3.86}/src/wiki/mod.rs +0 -0
  416. {seraplot-2.3.84 → seraplot-2.3.86}/test_accuracy.py +0 -0
  417. {seraplot-2.3.84 → seraplot-2.3.86}/test_universal_ml.js +0 -0
@@ -3471,7 +3471,7 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
3471
3471
 
3472
3472
  [[package]]
3473
3473
  name = "seraplot"
3474
- version = "2.3.84"
3474
+ version = "2.3.86"
3475
3475
  dependencies = [
3476
3476
  "base64 0.22.1",
3477
3477
  "criterion",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "seraplot"
3
- version = "2.3.84"
3
+ version = "2.3.86"
4
4
  edition = "2021"
5
5
  authors = ["feur25"]
6
6
  description = "Rust data visualization framework - The modern Plotly alternative"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seraplot
3
- Version: 2.3.84
3
+ Version: 2.3.86
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Environment :: Win32 (MS Windows)
6
6
  Classifier: Intended Audience :: Developers
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "seraplot"
7
- version = "2.3.84"
7
+ version = "2.3.86"
8
8
  description = "Rust data visualization framework - The modern Plotly alternative"
9
9
  readme = "README.md"
10
10
  readme-content-type = "text/markdown"
@@ -1583,6 +1583,156 @@ pub fn chart_info(input: &str) -> String {
1583
1583
  serde_json::json!({"size":len,"paths":n_paths,"rects":n_rects,"circles":n_circles,"has_svg":has_svg}).to_string()
1584
1584
  }
1585
1585
 
1586
+ pub fn validate_input(input: &str) -> String {
1587
+ #[derive(serde::Deserialize)]
1588
+ struct In { labels: Option<Vec<String>>, values: Option<Vec<f64>>, x: Option<Vec<f64>>, y: Option<Vec<f64>>, series: Option<Vec<Vec<f64>>> }
1589
+ let v: In = match serde_json::from_str::<In>(input) {
1590
+ Ok(v) => v,
1591
+ Err(e) => return serde_json::json!({"ok":false,"error":format!("invalid JSON: {e}")}).to_string(),
1592
+ };
1593
+ if let (Some(l), Some(va)) = (v.labels.as_ref(), v.values.as_ref()) {
1594
+ if l.len() != va.len() {
1595
+ return serde_json::json!({"ok":false,"error":format!("labels ({}) and values ({}) length mismatch", l.len(), va.len())}).to_string();
1596
+ }
1597
+ }
1598
+ if let (Some(x), Some(y)) = (v.x.as_ref(), v.y.as_ref()) {
1599
+ if x.len() != y.len() {
1600
+ return serde_json::json!({"ok":false,"error":format!("x ({}) and y ({}) length mismatch", x.len(), y.len())}).to_string();
1601
+ }
1602
+ }
1603
+ if let (Some(l), Some(s)) = (v.labels.as_ref(), v.series.as_ref()) {
1604
+ for (i, row) in s.iter().enumerate() {
1605
+ if row.len() != l.len() {
1606
+ return serde_json::json!({"ok":false,"error":format!("series[{i}] length {} != labels length {}", row.len(), l.len())}).to_string();
1607
+ }
1608
+ }
1609
+ }
1610
+ serde_json::json!({"ok":true}).to_string()
1611
+ }
1612
+
1613
+ pub fn downsample_lttb(input: &str) -> String {
1614
+ #[derive(serde::Deserialize)]
1615
+ struct In { x: Vec<f64>, y: Vec<f64>, threshold: usize }
1616
+ let v: In = match serde_json::from_str(input) {
1617
+ Ok(v) => v,
1618
+ Err(e) => return serde_json::json!({"ok":false,"error":format!("invalid JSON: {e}")}).to_string(),
1619
+ };
1620
+ let n = v.x.len();
1621
+ if n != v.y.len() {
1622
+ return serde_json::json!({"ok":false,"error":"x and y length mismatch"}).to_string();
1623
+ }
1624
+ let th = v.threshold;
1625
+ if th >= n || th < 3 {
1626
+ return serde_json::json!({"ok":true,"x":v.x,"y":v.y}).to_string();
1627
+ }
1628
+ let bucket_size = (n - 2) as f64 / (th - 2) as f64;
1629
+ let mut out_x: Vec<f64> = Vec::with_capacity(th);
1630
+ let mut out_y: Vec<f64> = Vec::with_capacity(th);
1631
+ out_x.push(v.x[0]); out_y.push(v.y[0]);
1632
+ let mut a: usize = 0;
1633
+ for i in 0..(th - 2) {
1634
+ let avg_start = ((i + 1) as f64 * bucket_size).floor() as usize + 1;
1635
+ let avg_end = (((i + 2) as f64 * bucket_size).floor() as usize + 1).min(n);
1636
+ let avg_len = (avg_end - avg_start).max(1) as f64;
1637
+ let mut avg_x = 0.0; let mut avg_y = 0.0;
1638
+ for k in avg_start..avg_end { avg_x += v.x[k]; avg_y += v.y[k]; }
1639
+ avg_x /= avg_len; avg_y /= avg_len;
1640
+ let range_offs = (i as f64 * bucket_size).floor() as usize + 1;
1641
+ let range_to = ((i + 1) as f64 * bucket_size).floor() as usize + 1;
1642
+ let pax = v.x[a]; let pay = v.y[a];
1643
+ let mut max_area = -1.0f64;
1644
+ let mut next_a = range_offs;
1645
+ for k in range_offs..range_to.min(n) {
1646
+ let area = ((pax - avg_x) * (v.y[k] - pay) - (pax - v.x[k]) * (avg_y - pay)).abs() * 0.5;
1647
+ if area > max_area { max_area = area; next_a = k; }
1648
+ }
1649
+ out_x.push(v.x[next_a]); out_y.push(v.y[next_a]);
1650
+ a = next_a;
1651
+ }
1652
+ out_x.push(v.x[n - 1]); out_y.push(v.y[n - 1]);
1653
+ serde_json::json!({"ok":true,"x":out_x,"y":out_y,"reduction":format!("{}->{}", n, out_x.len())}).to_string()
1654
+ }
1655
+
1656
+ pub fn chart_diff(input: &str) -> String {
1657
+ #[derive(serde::Deserialize)]
1658
+ struct In { a: String, b: String }
1659
+ let v: In = match serde_json::from_str(input) {
1660
+ Ok(v) => v,
1661
+ Err(_) => return serde_json::json!({"ok":false,"error":"invalid JSON"}).to_string(),
1662
+ };
1663
+ let svg_a = extract_svg(&v.a);
1664
+ let svg_b = extract_svg(&v.b);
1665
+ let identical = svg_a == svg_b;
1666
+ let len_a = svg_a.len();
1667
+ let len_b = svg_b.len();
1668
+ let common = svg_a.bytes().zip(svg_b.bytes()).take_while(|(x, y)| x == y).count();
1669
+ let similarity = if len_a == 0 && len_b == 0 { 1.0 } else {
1670
+ let max_len = len_a.max(len_b) as f64;
1671
+ common as f64 / max_len
1672
+ };
1673
+ serde_json::json!({
1674
+ "ok":true,
1675
+ "identical":identical,
1676
+ "size_a":len_a,
1677
+ "size_b":len_b,
1678
+ "common_prefix":common,
1679
+ "similarity":similarity
1680
+ }).to_string()
1681
+ }
1682
+
1683
+ fn extract_svg(html: &str) -> String {
1684
+ let start = match html.find("<svg") { Some(i) => i, None => return String::new() };
1685
+ let end = match html[start..].find("</svg>") { Some(i) => start + i + 6, None => return String::new() };
1686
+ html[start..end].to_string()
1687
+ }
1688
+
1689
+ pub fn drift_ks(input: &str) -> String {
1690
+ #[derive(serde::Deserialize)]
1691
+ struct In { reference: Vec<f64>, current: Vec<f64> }
1692
+ let v: In = match serde_json::from_str(input) {
1693
+ Ok(v) => v,
1694
+ Err(e) => return serde_json::json!({"ok":false,"error":format!("invalid JSON: {e}")}).to_string(),
1695
+ };
1696
+ let mut a = v.reference.clone();
1697
+ let mut b = v.current.clone();
1698
+ if a.is_empty() || b.is_empty() {
1699
+ return serde_json::json!({"ok":false,"error":"empty array"}).to_string();
1700
+ }
1701
+ a.sort_by(|x, y| x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal));
1702
+ b.sort_by(|x, y| x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal));
1703
+ let n = a.len() as f64;
1704
+ let m = b.len() as f64;
1705
+ let mut i = 0usize; let mut j = 0usize;
1706
+ let mut max_d = 0.0f64;
1707
+ while i < a.len() && j < b.len() {
1708
+ let cdf_a = (i + 1) as f64 / n;
1709
+ let cdf_b = (j + 1) as f64 / m;
1710
+ let d = (cdf_a - cdf_b).abs();
1711
+ if d > max_d { max_d = d; }
1712
+ if a[i] <= b[j] { i += 1; } else { j += 1; }
1713
+ }
1714
+ let coeff = ((n * m) / (n + m)).sqrt();
1715
+ let lambda = (coeff + 0.12 + 0.11 / coeff) * max_d;
1716
+ let mut p_value = 0.0f64;
1717
+ let mut sign = 1.0f64;
1718
+ for k in 1..=100 {
1719
+ let term = sign * 2.0 * (-2.0 * lambda * lambda * (k * k) as f64).exp();
1720
+ p_value += term;
1721
+ sign = -sign;
1722
+ if term.abs() < 1e-10 { break; }
1723
+ }
1724
+ p_value = p_value.clamp(0.0, 1.0);
1725
+ let drift_detected = p_value < 0.05;
1726
+ serde_json::json!({
1727
+ "ok":true,
1728
+ "ks_statistic":max_d,
1729
+ "p_value":p_value,
1730
+ "drift_detected":drift_detected,
1731
+ "n_reference":a.len(),
1732
+ "n_current":b.len()
1733
+ }).to_string()
1734
+ }
1735
+
1586
1736
  pub fn bench_chart_value(s: &str) -> bool {
1587
1737
  serde_json::from_str::<serde_json::Value>(s).is_ok()
1588
1738
  }
@@ -39,6 +39,12 @@ pub fn register_submodules(py: Python<'_>, m: &PyModule) -> PyResult<()> {
39
39
  m.add_function(wrap_pyfunction!(export_png, m)?)?;
40
40
  m.add_function(wrap_pyfunction!(chart_info, m)?)?;
41
41
  m.add_class::<LiveStream>()?;
42
+ m.add_function(wrap_pyfunction!(facet, m)?)?;
43
+ m.add_function(wrap_pyfunction!(drift, m)?)?;
44
+ m.add_function(wrap_pyfunction!(lttb, m)?)?;
45
+ m.add_function(wrap_pyfunction!(show, m)?)?;
46
+ m.add_function(wrap_pyfunction!(auto_classify, m)?)?;
47
+ m.add_class::<Pipeline>()?;
42
48
 
43
49
  for (alias, canonical) in crate::bindings::registry_macro::CHART_ALIASES {
44
50
  if let Ok(func) = m.getattr(*canonical) {
@@ -187,6 +187,10 @@ macro_rules! for_each_fn {
187
187
  $mac!(ml_save_model, "mlSaveModel");
188
188
  $mac!(ml_load_model, "mlLoadModel");
189
189
  $mac!(chart_info, "chartInfo");
190
+ $mac!(validate_input, "validateInput");
191
+ $mac!(downsample_lttb, "downsampleLttb");
192
+ $mac!(chart_diff, "chartDiff");
193
+ $mac!(drift_ks, "driftKs");
190
194
  };
191
195
  }
192
196
 
@@ -619,5 +623,158 @@ macro_rules! impl_python_bindings {
619
623
  pub fn clear(&mut self) { self.xs.clear(); self.ys.clear(); }
620
624
  #[getter] pub fn n(&self) -> usize { self.xs.len() }
621
625
  }
626
+
627
+ #[pyfunction]
628
+ #[pyo3(signature = (charts, cols=2, gap=16, bg=None, cell_height=520))]
629
+ pub fn facet(
630
+ charts: Vec<pyo3::PyRef<crate::Chart>>,
631
+ cols: usize,
632
+ gap: i32,
633
+ bg: Option<&str>,
634
+ cell_height: i32,
635
+ ) -> crate::Chart {
636
+ let html_strs: Vec<String> = charts.iter().map(|c| c.html.clone()).collect();
637
+ crate::Chart::new(
638
+ crate::bindings::commands::charts::build_grid(
639
+ &serde_json::json!({"charts": html_strs, "cols": cols, "gap": gap, "background": bg, "cell_height": cell_height}).to_string()
640
+ )
641
+ )
642
+ }
643
+
644
+ #[pyfunction]
645
+ #[pyo3(signature = (reference, current))]
646
+ pub fn drift(reference: Vec<f64>, current: Vec<f64>) -> String {
647
+ crate::bindings::commands::charts::drift_ks(
648
+ &serde_json::json!({"reference": reference, "current": current}).to_string()
649
+ )
650
+ }
651
+
652
+ #[pyfunction]
653
+ #[pyo3(signature = (input, threshold=2000))]
654
+ pub fn lttb(input: Vec<(f64, f64)>, threshold: usize) -> Vec<(f64, f64)> {
655
+ let xs: Vec<f64> = input.iter().map(|p| p.0).collect();
656
+ let ys: Vec<f64> = input.iter().map(|p| p.1).collect();
657
+ let res = crate::bindings::commands::charts::downsample_lttb(
658
+ &serde_json::json!({"x": xs, "y": ys, "threshold": threshold}).to_string()
659
+ );
660
+ let v: serde_json::Value = match serde_json::from_str(&res) { Ok(v) => v, Err(_) => return input };
661
+ let nx: Vec<f64> = v.get("x").and_then(|a| a.as_array()).map(|a| a.iter().filter_map(|n| n.as_f64()).collect()).unwrap_or_default();
662
+ let ny: Vec<f64> = v.get("y").and_then(|a| a.as_array()).map(|a| a.iter().filter_map(|n| n.as_f64()).collect()).unwrap_or_default();
663
+ nx.into_iter().zip(ny).collect()
664
+ }
665
+
666
+ #[pyfunction]
667
+ pub fn show(py: Python<'_>, chart: &crate::Chart) -> PyResult<()> {
668
+ chart.show(py)
669
+ }
670
+
671
+ #[pyfunction]
672
+ #[pyo3(signature = (x, y, models=None))]
673
+ pub fn auto_classify(py: Python<'_>, x: &PyAny, y: Vec<i64>, models: Option<Vec<String>>) -> PyResult<pyo3::Py<pyo3::types::PyDict>> {
674
+ let (flat, n, dims) = crate::bindings::commands::ml::extract_flat(x)?;
675
+ let chosen = models.unwrap_or_else(|| vec![
676
+ "logistic".to_string(),
677
+ "knn".to_string(),
678
+ "decision_tree".to_string(),
679
+ "random_forest".to_string(),
680
+ "gradient_boosting".to_string(),
681
+ ]);
682
+ let mut leaderboard: Vec<(String, f64)> = Vec::new();
683
+ for name in chosen.iter() {
684
+ let payload = serde_json::json!({"x": flat, "n": n, "dims": dims, "y": y}).to_string();
685
+ let raw = match name.as_str() {
686
+ "logistic" => crate::bindings::commands::charts::ml_logistic_regression(&payload),
687
+ "knn" => crate::bindings::commands::charts::ml_knn_classifier(&payload),
688
+ "decision_tree" => crate::bindings::commands::charts::ml_decision_tree_classifier(&payload),
689
+ "random_forest" => crate::bindings::commands::charts::ml_random_forest_classifier(&payload),
690
+ "gradient_boosting" => crate::bindings::commands::charts::ml_gradient_boosting_classifier(&payload),
691
+ _ => continue,
692
+ };
693
+ let score = serde_json::from_str::<serde_json::Value>(&raw).ok()
694
+ .and_then(|v| v.get("score").and_then(|s| s.as_f64()))
695
+ .or_else(|| serde_json::from_str::<serde_json::Value>(&raw).ok().and_then(|v| v.get("accuracy").and_then(|s| s.as_f64())))
696
+ .unwrap_or(f64::NAN);
697
+ leaderboard.push((name.clone(), score));
698
+ }
699
+ leaderboard.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
700
+ let dict = pyo3::types::PyDict::new(py);
701
+ let lb = pyo3::types::PyList::empty(py);
702
+ for (name, score) in leaderboard.iter() {
703
+ let row = pyo3::types::PyDict::new(py);
704
+ row.set_item("model", name)?;
705
+ row.set_item("score", score)?;
706
+ lb.append(row)?;
707
+ }
708
+ dict.set_item("leaderboard", lb)?;
709
+ if let Some((best_name, best_score)) = leaderboard.first() {
710
+ dict.set_item("best_model", best_name)?;
711
+ dict.set_item("best_score", best_score)?;
712
+ }
713
+ Ok(dict.into())
714
+ }
715
+
716
+ #[pyclass(module = "seraplot", name = "Pipeline")]
717
+ pub struct Pipeline {
718
+ steps: Vec<(String, pyo3::PyObject)>,
719
+ }
720
+
721
+ #[pymethods]
722
+ impl Pipeline {
723
+ #[new]
724
+ #[pyo3(signature = (steps))]
725
+ pub fn py_new(steps: Vec<(String, pyo3::PyObject)>) -> Self {
726
+ Self { steps }
727
+ }
728
+ pub fn fit(&mut self, py: Python<'_>, x: &PyAny, y: Option<&PyAny>) -> PyResult<()> {
729
+ let mut current: pyo3::PyObject = x.into();
730
+ for (i, (_, step)) in self.steps.iter().enumerate() {
731
+ let st = step.as_ref(py);
732
+ let is_last = i == self.steps.len() - 1;
733
+ if is_last {
734
+ if let Some(yy) = y {
735
+ if st.call_method1("fit", (current.as_ref(py), yy)).is_err() {
736
+ let _ = st.call_method1("fit", (current.as_ref(py),));
737
+ }
738
+ } else {
739
+ let _ = st.call_method1("fit", (current.as_ref(py),));
740
+ }
741
+ } else {
742
+ let _ = st.call_method1("fit", (current.as_ref(py),));
743
+ if let Ok(t) = st.call_method1("transform", (current.as_ref(py),)) {
744
+ current = t.into();
745
+ }
746
+ }
747
+ }
748
+ Ok(())
749
+ }
750
+ pub fn predict(&self, py: Python<'_>, x: &PyAny) -> PyResult<pyo3::PyObject> {
751
+ let mut current: pyo3::PyObject = x.into();
752
+ for (i, (_, step)) in self.steps.iter().enumerate() {
753
+ let st = step.as_ref(py);
754
+ let is_last = i == self.steps.len() - 1;
755
+ if is_last {
756
+ return Ok(st.call_method1("predict", (current.as_ref(py),))?.into());
757
+ }
758
+ if let Ok(t) = st.call_method1("transform", (current.as_ref(py),)) {
759
+ current = t.into();
760
+ }
761
+ }
762
+ Ok(current)
763
+ }
764
+ pub fn transform(&self, py: Python<'_>, x: &PyAny) -> PyResult<pyo3::PyObject> {
765
+ let mut current: pyo3::PyObject = x.into();
766
+ for (_, step) in self.steps.iter() {
767
+ let st = step.as_ref(py);
768
+ if let Ok(t) = st.call_method1("transform", (current.as_ref(py),)) {
769
+ current = t.into();
770
+ }
771
+ }
772
+ Ok(current)
773
+ }
774
+ #[getter] pub fn step_names(&self) -> Vec<String> { self.steps.iter().map(|(n, _)| n.clone()).collect() }
775
+ fn __repr__(&self) -> String {
776
+ format!("Pipeline(steps={:?})", self.steps.iter().map(|(n, _)| n.clone()).collect::<Vec<_>>())
777
+ }
778
+ }
622
779
  };
623
780
  }
@@ -130,6 +130,17 @@
130
130
  - [Auto Display](config/auto-display.md)
131
131
  - [Hover JSON](config/hover.md)
132
132
  - [Palette](config/palette.md)
133
+ - [Export (SVG / PNG / Data URL)](config/export.md)
134
+ - [Live Streaming](config/streaming.md)
135
+ - [ML Persistence](config/ml-persistence.md)
136
+ - [Faceting / Small Multiples](config/facet.md)
137
+ - [Downsampling (LTTB)](config/downsample.md)
138
+ - [Chart Diff](config/diff.md)
139
+ - [Accessibility (a11y)](config/a11y.md)
140
+ - [CSP-safe Mode](config/csp.md)
141
+ - [Pickle / Serialization](config/pickle.md)
142
+ - [AutoML & Pipeline](config/automl.md)
143
+ - [Drift Detection](config/drift.md)
133
144
 
134
145
  ---
135
146
 
@@ -0,0 +1,41 @@
1
+ # Accessibility (a11y)
2
+
3
+ <div class="lang-en">
4
+
5
+ Inject ARIA roles, `<title>` and `<desc>` into the chart SVG for screen readers and B2B compliance (WCAG 2.1).
6
+
7
+ ## Python
8
+
9
+ ```python
10
+ import seraplot as sp
11
+
12
+ chart = (
13
+ sp.bar([10,20,30], ["EU","US","APAC"])
14
+ .a11y(title="Quarterly revenue by region",
15
+ desc="Bar chart, EU 10M, US 20M, APAC 30M")
16
+ )
17
+ ```
18
+
19
+ The resulting SVG includes `role="img"`, `aria-label`, `<title>`, `<desc>` — recognized by NVDA, JAWS, VoiceOver.
20
+
21
+ </div>
22
+
23
+ <div class="lang-fr">
24
+
25
+ Injecte les rôles ARIA, `<title>` et `<desc>` dans le SVG pour les lecteurs d'écran et la conformité B2B (WCAG 2.1).
26
+
27
+ ## Python
28
+
29
+ ```python
30
+ import seraplot as sp
31
+
32
+ chart = (
33
+ sp.bar([10,20,30], ["EU","US","APAC"])
34
+ .a11y(title="Revenu trimestriel par région",
35
+ desc="Bar chart, EU 10M, US 20M, APAC 30M")
36
+ )
37
+ ```
38
+
39
+ Le SVG résultant inclut `role="img"`, `aria-label`, `<title>`, `<desc>` — reconnus par NVDA, JAWS, VoiceOver.
40
+
41
+ </div>
@@ -0,0 +1,69 @@
1
+ # AutoML & Pipeline
2
+
3
+ <div class="lang-en">
4
+
5
+ ## auto_classify
6
+
7
+ Try several classifiers, return the leaderboard sorted by score.
8
+
9
+ ```python
10
+ import seraplot as sp
11
+
12
+ result = sp.auto_classify(X_train, y_train)
13
+ print(result["best_model"], result["best_score"])
14
+ for row in result["leaderboard"]:
15
+ print(row)
16
+ ```
17
+
18
+ Default models: `logistic`, `knn`, `decision_tree`, `random_forest`, `gradient_boosting`. Customize with `models=["random_forest","knn"]`.
19
+
20
+ ## Pipeline
21
+
22
+ Chain transformers + estimator (sklearn-compatible API).
23
+
24
+ ```python
25
+ from seraplot import StandardScaler, RandomForestClassifier, Pipeline
26
+
27
+ pipe = Pipeline([
28
+ ("scaler", StandardScaler()),
29
+ ("model", RandomForestClassifier(n_estimators=200)),
30
+ ])
31
+ pipe.fit(X_train, y_train)
32
+ preds = pipe.predict(X_test)
33
+ ```
34
+
35
+ </div>
36
+
37
+ <div class="lang-fr">
38
+
39
+ ## auto_classify
40
+
41
+ Essaie plusieurs classifieurs, retourne le leaderboard trié par score.
42
+
43
+ ```python
44
+ import seraplot as sp
45
+
46
+ result = sp.auto_classify(X_train, y_train)
47
+ print(result["best_model"], result["best_score"])
48
+ for row in result["leaderboard"]:
49
+ print(row)
50
+ ```
51
+
52
+ Modèles par défaut : `logistic`, `knn`, `decision_tree`, `random_forest`, `gradient_boosting`. Personnalisable avec `models=["random_forest","knn"]`.
53
+
54
+ ## Pipeline
55
+
56
+ Enchaîne transformers + estimateur (API compatible sklearn).
57
+
58
+ ```python
59
+ from seraplot import StandardScaler, RandomForestClassifier, Pipeline
60
+
61
+ pipe = Pipeline([
62
+ ("scaler", StandardScaler()),
63
+ ("model", RandomForestClassifier(n_estimators=200)),
64
+ ])
65
+ pipe.fit(X_train, y_train)
66
+ preds = pipe.predict(X_test)
67
+ ```
68
+
69
+ </div>
@@ -0,0 +1,33 @@
1
+ # CSP-safe Mode
2
+
3
+ <div class="lang-en">
4
+
5
+ Strict Content Security Policies block inline `<script>`. The `csp_safe()` method extracts JS into a `<script type="application/json">` payload + a single nonce-able loader.
6
+
7
+ ## Python
8
+
9
+ ```python
10
+ import seraplot as sp
11
+
12
+ chart = sp.line([1,2,3,4], [10,20,15,25]).csp_safe()
13
+ ```
14
+
15
+ Apply your CSP `script-src 'nonce-sp-nonce'` and the chart still renders.
16
+
17
+ </div>
18
+
19
+ <div class="lang-fr">
20
+
21
+ Les CSP strictes bloquent les `<script>` inline. La méthode `csp_safe()` extrait le JS dans un payload `<script type="application/json">` + un loader unique compatible nonce.
22
+
23
+ ## Python
24
+
25
+ ```python
26
+ import seraplot as sp
27
+
28
+ chart = sp.line([1,2,3,4], [10,20,15,25]).csp_safe()
29
+ ```
30
+
31
+ Applique ta CSP `script-src 'nonce-sp-nonce'` et le chart se rend toujours.
32
+
33
+ </div>
@@ -0,0 +1,53 @@
1
+ # Chart Diff
2
+
3
+ <div class="lang-en">
4
+
5
+ Compare two charts structurally — useful for visual CI / regression testing.
6
+
7
+ ## Python
8
+
9
+ ```python
10
+ import seraplot as sp
11
+
12
+ a = sp.bar([1,2,3], ["x","y","z"])
13
+ b = sp.bar([1,2,4], ["x","y","z"])
14
+ result = a.diff(b)
15
+ print(result)
16
+ ```
17
+
18
+ Returns JSON: `{ "ok": true, "identical": false, "size_a": 4521, "size_b": 4523, "common_prefix": 4400, "similarity": 0.97 }`.
19
+
20
+ ## JavaScript
21
+
22
+ ```javascript
23
+ import { chartDiff } from "seraplot";
24
+ const diff = JSON.parse(chartDiff(JSON.stringify({ a: htmlA, b: htmlB })));
25
+ ```
26
+
27
+ </div>
28
+
29
+ <div class="lang-fr">
30
+
31
+ Compare deux charts structurellement — utile pour les CI visuelles / tests de régression.
32
+
33
+ ## Python
34
+
35
+ ```python
36
+ import seraplot as sp
37
+
38
+ a = sp.bar([1,2,3], ["x","y","z"])
39
+ b = sp.bar([1,2,4], ["x","y","z"])
40
+ result = a.diff(b)
41
+ print(result)
42
+ ```
43
+
44
+ Retourne du JSON : `{ "ok": true, "identical": false, "size_a": 4521, "size_b": 4523, "common_prefix": 4400, "similarity": 0.97 }`.
45
+
46
+ ## JavaScript
47
+
48
+ ```javascript
49
+ import { chartDiff } from "seraplot";
50
+ const diff = JSON.parse(chartDiff(JSON.stringify({ a: htmlA, b: htmlB })));
51
+ ```
52
+
53
+ </div>
@@ -0,0 +1,63 @@
1
+ # Downsampling (LTTB)
2
+
3
+ <div class="lang-en">
4
+
5
+ Reduce massive datasets while preserving visual shape using the **Largest-Triangle-Three-Buckets** algorithm. A 10M-point scatter chart becomes 5K points indistinguishable to the eye.
6
+
7
+ ## Python
8
+
9
+ ```python
10
+ import seraplot as sp
11
+
12
+ chart = sp.scatter(big_x, big_y).downsample(n=5000)
13
+
14
+ points = sp.lttb(list(zip(big_x, big_y)), threshold=5000)
15
+ ```
16
+
17
+ ## JavaScript
18
+
19
+ ```javascript
20
+ import { downsampleLttb } from "seraplot";
21
+ const reduced = JSON.parse(downsampleLttb(JSON.stringify({ x, y, threshold: 5000 })));
22
+ ```
23
+
24
+ ## Why LTTB?
25
+
26
+ | Method | Preserves peaks | Speed | Visual fidelity |
27
+ |--------|----------------|-------|-----------------|
28
+ | Random sample | No | Fast | Poor |
29
+ | Every-Nth | Maybe | Fast | OK |
30
+ | **LTTB** | Yes | Fast | Excellent |
31
+
32
+ </div>
33
+
34
+ <div class="lang-fr">
35
+
36
+ Réduit les datasets massifs en préservant la forme visuelle avec l'algorithme **Largest-Triangle-Three-Buckets**. Un scatter de 10M points devient 5K points indistinguables à l'œil.
37
+
38
+ ## Python
39
+
40
+ ```python
41
+ import seraplot as sp
42
+
43
+ chart = sp.scatter(big_x, big_y).downsample(n=5000)
44
+
45
+ points = sp.lttb(list(zip(big_x, big_y)), threshold=5000)
46
+ ```
47
+
48
+ ## JavaScript
49
+
50
+ ```javascript
51
+ import { downsampleLttb } from "seraplot";
52
+ const reduced = JSON.parse(downsampleLttb(JSON.stringify({ x, y, threshold: 5000 })));
53
+ ```
54
+
55
+ ## Pourquoi LTTB ?
56
+
57
+ | Méthode | Préserve les pics | Vitesse | Fidélité visuelle |
58
+ |---------|-------------------|---------|-------------------|
59
+ | Échantillon aléatoire | Non | Rapide | Mauvaise |
60
+ | Tous les N | Peut-être | Rapide | OK |
61
+ | **LTTB** | Oui | Rapide | Excellente |
62
+
63
+ </div>