quantized-lab 0.9.0__tar.gz → 0.11.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 (248) hide show
  1. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/.gitignore +7 -0
  2. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/PKG-INFO +1 -1
  3. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/pyproject.toml +1 -1
  4. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/__init__.py +1 -1
  5. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/app.py +4 -0
  6. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure.py +75 -25
  7. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_break.py +10 -4
  8. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_categorical.py +39 -22
  9. quantized_lab-0.11.0/src/quantized/calc/figure_facets.py +359 -0
  10. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_labels.py +46 -14
  11. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_overrides.py +27 -4
  12. quantized_lab-0.11.0/src/quantized/calc/figure_page.py +449 -0
  13. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_scale.py +4 -1
  14. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_ticks.py +53 -3
  15. quantized_lab-0.11.0/src/quantized/calc/figure_y2.py +266 -0
  16. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_bumps.py +30 -4
  17. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_scan.py +2 -7
  18. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fitting.py +29 -0
  19. quantized_lab-0.11.0/src/quantized/calc/plotting.py +278 -0
  20. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/semiconductor.py +11 -0
  21. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/datastruct.py +22 -3
  22. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/delimited.py +53 -2
  23. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/curve_style_color.py +13 -8
  24. quantized_lab-0.11.0/src/quantized/io/origin_project/fidelity.py +194 -0
  25. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/figure_layers.py +13 -1
  26. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/figure_text.py +36 -0
  27. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/figures.py +13 -3
  28. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/figures_opju.py +2 -0
  29. quantized_lab-0.11.0/src/quantized/io/origin_project/graph_preview.py +156 -0
  30. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opj_curves.py +87 -22
  31. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_figure_text.py +6 -0
  32. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/templates.py +5 -3
  33. quantized_lab-0.11.0/src/quantized/io/sqlite_query.py +145 -0
  34. quantized_lab-0.11.0/src/quantized/routes/database.py +62 -0
  35. quantized_lab-0.11.0/src/quantized/routes/export_figures.py +467 -0
  36. quantized_lab-0.11.0/src/quantized/routes/export_figures_aux.py +227 -0
  37. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/export_page.py +27 -6
  38. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/fitting.py +20 -3
  39. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/parsers.py +31 -6
  40. quantized_lab-0.11.0/src/quantized/web/assets/index-CQDio8Fq.css +1 -0
  41. quantized_lab-0.11.0/src/quantized/web/assets/index-jFkYmKQl.js +27 -0
  42. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/web/index.html +2 -2
  43. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/tools/origin_compare/README.md +1 -1
  44. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/tools/visual/README.md +44 -5
  45. quantized_lab-0.9.0/src/quantized/calc/figure_facets.py +0 -127
  46. quantized_lab-0.9.0/src/quantized/calc/figure_page.py +0 -266
  47. quantized_lab-0.9.0/src/quantized/calc/plotting.py +0 -147
  48. quantized_lab-0.9.0/src/quantized/routes/export_figures.py +0 -471
  49. quantized_lab-0.9.0/src/quantized/web/assets/index-BiZzN7J6.css +0 -1
  50. quantized_lab-0.9.0/src/quantized/web/assets/index-D8RNGjHO.js +0 -27
  51. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/LICENSE +0 -0
  52. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/NOTICE +0 -0
  53. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/README.md +0 -0
  54. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/__main__.py +0 -0
  55. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/api.py +0 -0
  56. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/__init__.py +0 -0
  57. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/_clipfit.py +0 -0
  58. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/_natural_neighbor.py +0 -0
  59. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/aggregate.py +0 -0
  60. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/backgrounds.py +0 -0
  61. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/baseline.py +0 -0
  62. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/batch_fit.py +0 -0
  63. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/constants.py +0 -0
  64. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/corrections.py +0 -0
  65. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/crystallography.py +0 -0
  66. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/diffusion.py +0 -0
  67. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/electrical.py +0 -0
  68. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/electrochemistry.py +0 -0
  69. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/element_data.json +0 -0
  70. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/element_data.py +0 -0
  71. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/errors.py +0 -0
  72. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_corner.py +0 -0
  73. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_field.py +0 -0
  74. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_hitmap.py +0 -0
  75. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_map.py +0 -0
  76. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_shapes.py +0 -0
  77. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_statplots.py +0 -0
  78. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_styles.py +0 -0
  79. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/figure_ternary.py +0 -0
  80. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_autoguess.py +0 -0
  81. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_bootstrap.py +0 -0
  82. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_constraints.py +0 -0
  83. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_equation.py +0 -0
  84. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_findxy.py +0 -0
  85. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_models.py +0 -0
  86. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_models_special.py +0 -0
  87. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_odr.py +0 -0
  88. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/fit_stats.py +0 -0
  89. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/formula.py +0 -0
  90. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/global_curve_fit.py +0 -0
  91. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/global_fit.py +0 -0
  92. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/interp2d.py +0 -0
  93. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/linecut.py +0 -0
  94. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/magnetic.py +0 -0
  95. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/magnetometry.py +0 -0
  96. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/map.py +0 -0
  97. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/mcmc.py +0 -0
  98. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/optics.py +0 -0
  99. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/pawley.py +0 -0
  100. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/peak_batch.py +0 -0
  101. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/peak_fit.py +0 -0
  102. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/peak_integrate.py +0 -0
  103. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/peak_multifit.py +0 -0
  104. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/peak_track.py +0 -0
  105. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/peaks.py +0 -0
  106. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/peakshapes.py +0 -0
  107. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/processing.py +0 -0
  108. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/qspace.py +0 -0
  109. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/reductions.py +0 -0
  110. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/reductions_fft.py +0 -0
  111. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/refl_sld_presets.json +0 -0
  112. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/reflectivity.py +0 -0
  113. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/registry.py +0 -0
  114. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/relaxation.py +0 -0
  115. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/report.py +0 -0
  116. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/report_emit.py +0 -0
  117. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/resample.py +0 -0
  118. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/rsm.py +0 -0
  119. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/rsm_analyze.py +0 -0
  120. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/sld.py +0 -0
  121. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/sld_formula.py +0 -0
  122. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/spectral.py +0 -0
  123. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/statplots.py +0 -0
  124. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats.py +0 -0
  125. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_anova2.py +0 -0
  126. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_anova_ext.py +0 -0
  127. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_dist.py +0 -0
  128. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_glm.py +0 -0
  129. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_multivar.py +0 -0
  130. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_roc.py +0 -0
  131. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_survival.py +0 -0
  132. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/stats_tests.py +0 -0
  133. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/substrates.py +0 -0
  134. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/superconductor.py +0 -0
  135. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/surface_fit.py +0 -0
  136. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/surface_models.py +0 -0
  137. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/thermal.py +0 -0
  138. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/thin_film.py +0 -0
  139. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/unit_convert.py +0 -0
  140. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/units.py +0 -0
  141. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/vacuum.py +0 -0
  142. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/calc/xray.py +0 -0
  143. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/cli.py +0 -0
  144. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/__init__.py +0 -0
  145. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/_hdf5_layout.py +0 -0
  146. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/_jcamp_asdf.py +0 -0
  147. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/_xrdml_scan.py +0 -0
  148. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/base.py +0 -0
  149. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/bruker_brml.py +0 -0
  150. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/bruker_raw.py +0 -0
  151. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/cif.py +0 -0
  152. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/consolidated.py +0 -0
  153. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/excel.py +0 -0
  154. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/hdf5.py +0 -0
  155. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/import_filters.py +0 -0
  156. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/import_preview.py +0 -0
  157. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/jcamp.py +0 -0
  158. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/lakeshore.py +0 -0
  159. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/ncnr.py +0 -0
  160. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/netcdf.py +0 -0
  161. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/opus.py +0 -0
  162. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin.py +0 -0
  163. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_com.py +0 -0
  164. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/__init__.py +0 -0
  165. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/annotation_marks.py +0 -0
  166. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/container.py +0 -0
  167. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/figure_geometry.py +0 -0
  168. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/notes.py +0 -0
  169. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opj.py +0 -0
  170. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opj_shapes.py +0 -0
  171. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju.py +0 -0
  172. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_axis_real_form.py +0 -0
  173. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_axis_specimen_form.py +0 -0
  174. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_codec.py +0 -0
  175. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_curves.py +0 -0
  176. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_curves_allcols.py +0 -0
  177. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_figure_curves.py +0 -0
  178. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/opju_reports.py +0 -0
  179. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/origin_richtext.py +0 -0
  180. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/preview.py +0 -0
  181. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/tree.py +0 -0
  182. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/tree_opju.py +0 -0
  183. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/windows.py +0 -0
  184. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/windows_opju.py +0 -0
  185. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/writer.py +0 -0
  186. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/origin_project/writer_blocks.py +0 -0
  187. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/qd.py +0 -0
  188. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/refl1d.py +0 -0
  189. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/registry.py +0 -0
  190. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/report_export.py +0 -0
  191. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/rigaku.py +0 -0
  192. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/sims.py +0 -0
  193. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/spc.py +0 -0
  194. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/xrd_csv.py +0 -0
  195. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/io/xrdml.py +0 -0
  196. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/jobs.py +0 -0
  197. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/plugins/__init__.py +0 -0
  198. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/plugins/contract.py +0 -0
  199. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/plugins/loader.py +0 -0
  200. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/plugins/steps.py +0 -0
  201. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/__init__.py +0 -0
  202. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/_bookcache.py +0 -0
  203. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/_export_common.py +0 -0
  204. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/_payload.py +0 -0
  205. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/_uploadcache.py +0 -0
  206. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/aggregate.py +0 -0
  207. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/baseline.py +0 -0
  208. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/books.py +0 -0
  209. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/calc.py +0 -0
  210. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/corrections.py +0 -0
  211. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/crystallography.py +0 -0
  212. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/diffusion.py +0 -0
  213. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/electrical.py +0 -0
  214. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/electrochemistry.py +0 -0
  215. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/export.py +0 -0
  216. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/export_facets.py +0 -0
  217. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/fitting_bumps.py +0 -0
  218. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/import_template.py +0 -0
  219. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/import_wizard.py +0 -0
  220. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/jobs_api.py +0 -0
  221. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/magnetic.py +0 -0
  222. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/magnetometry.py +0 -0
  223. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/optics.py +0 -0
  224. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/peaks.py +0 -0
  225. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/plot.py +0 -0
  226. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/reductions.py +0 -0
  227. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/reference.py +0 -0
  228. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/reflectivity.py +0 -0
  229. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/report_export.py +0 -0
  230. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/rsm.py +0 -0
  231. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/samples.py +0 -0
  232. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/semiconductor.py +0 -0
  233. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/sld.py +0 -0
  234. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/spectral.py +0 -0
  235. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/statplots.py +0 -0
  236. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/stats.py +0 -0
  237. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/stats_design.py +0 -0
  238. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/substrates.py +0 -0
  239. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/superconductor.py +0 -0
  240. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/thermal.py +0 -0
  241. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/thin_film.py +0 -0
  242. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/vacuum.py +0 -0
  243. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/routes/xray.py +0 -0
  244. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/samples/demo_vsm.csv +0 -0
  245. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/server_launch.py +0 -0
  246. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/web/assets/JetBrainsMono-Bold-CUogYd9I.woff2 +0 -0
  247. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/web/assets/JetBrainsMono-Regular-CA-Os4ii.woff2 +0 -0
  248. {quantized_lab-0.9.0 → quantized_lab-0.11.0}/src/quantized/web/loading.html +0 -0
@@ -16,6 +16,13 @@ node_modules/
16
16
  frontend/dist/
17
17
  *.tsbuildinfo
18
18
 
19
+ # ── Playwright E2E (GUI_INTERACTION_PLAN #15) ──────────────────────────
20
+ frontend/test-results/
21
+ frontend/playwright-report/
22
+ frontend/e2e/test-results/
23
+ frontend/e2e/playwright-report/
24
+ frontend/blob-report/
25
+
19
26
  # ── Tauri / desktop ───────────────────────────────────────────────────
20
27
  src-tauri/target/
21
28
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quantized-lab
3
- Version: 0.9.0
3
+ Version: 0.11.0
4
4
  Summary: Plot, analyze, and publish lab data - magnetometry, XRD, reflectometry - with OriginPro file interop, golden-verified analysis, and reproducible pipelines.
5
5
  Project-URL: Homepage, https://github.com/pquarterman17/quantized
6
6
  Project-URL: Documentation, https://github.com/pquarterman17/quantized/wiki
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "quantized-lab"
3
- version = "0.9.0"
3
+ version = "0.11.0"
4
4
  description = "Plot, analyze, and publish lab data - magnetometry, XRD, reflectometry - with OriginPro file interop, golden-verified analysis, and reproducible pipelines."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -7,5 +7,5 @@ Layered, enforced architecture (see CLAUDE.md):
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- __version__ = "0.9.0"
10
+ __version__ = "0.11.0"
11
11
  __all__ = ["__version__"]
@@ -25,12 +25,14 @@ from quantized.routes import (
25
25
  calc,
26
26
  corrections,
27
27
  crystallography,
28
+ database,
28
29
  diffusion,
29
30
  electrical,
30
31
  electrochemistry,
31
32
  export,
32
33
  export_facets,
33
34
  export_figures,
35
+ export_figures_aux,
34
36
  export_page,
35
37
  fitting,
36
38
  fitting_bumps,
@@ -146,6 +148,7 @@ def create_app() -> FastAPI:
146
148
  application.include_router(import_template.router)
147
149
  application.include_router(plot.router)
148
150
  application.include_router(corrections.router)
151
+ application.include_router(database.router)
149
152
  application.include_router(fitting.router)
150
153
  application.include_router(fitting_bumps.router)
151
154
  application.include_router(jobs_api.router)
@@ -156,6 +159,7 @@ def create_app() -> FastAPI:
156
159
  application.include_router(reference.router)
157
160
  application.include_router(export.router)
158
161
  application.include_router(export_figures.router)
162
+ application.include_router(export_figures_aux.router)
159
163
  application.include_router(export_facets.router)
160
164
  application.include_router(export_page.router)
161
165
  application.include_router(report_export.router)
@@ -27,12 +27,12 @@ from quantized.calc.figure_labels import safe_mathtext_label # noqa: E402
27
27
  from quantized.calc.figure_overrides import _apply_overrides, _validate_overrides # noqa: E402
28
28
  from quantized.calc.figure_scale import apply_axis_scale, resolve_axis_scale # noqa: E402
29
29
  from quantized.calc.figure_styles import FigureStyle, figure_style # noqa: E402
30
- from quantized.calc.figure_ticks import apply_tick_formats # noqa: E402
30
+ from quantized.calc.figure_ticks import apply_tick_formats, apply_tick_steps # noqa: E402
31
31
 
32
32
  __all__ = ["draw_series_axes", "render_figure", "style_rc"]
33
33
 
34
34
  _FORMATS = ("pdf", "svg", "png", "tiff")
35
- _LINESTYLE = {"solid": "-", "dashed": "--", "dotted": ":"}
35
+ _LINESTYLE = {"solid": "-", "dashed": "--", "dotted": ":", "none": "none"}
36
36
  # Fixed fill translucency for MAIN #13 (fill under/between curves) — matches
37
37
  # the screen side's `uplotFill.ts` FILL_ALPHA_PCT (25%) so an exported figure
38
38
  # reads the same as its on-screen counterpart.
@@ -177,6 +177,8 @@ def draw_series_axes(
177
177
  series_styles: Sequence[Mapping[str, Any] | None] | None = None,
178
178
  x_fmt: Mapping[str, Any] | None = None,
179
179
  y_fmt: Mapping[str, Any] | None = None,
180
+ x_step: float | None = None,
181
+ y_step: float | None = None,
180
182
  ) -> list[Any]:
181
183
  """Plot ``series`` into an EXISTING Axes: lines, scales, labels, spines,
182
184
  legend, grid, and the per-figure override sweep (:func:`_apply_overrides`).
@@ -221,8 +223,11 @@ def draw_series_axes(
221
223
  (line,) = ax.plot(xv, yv, label=label, **kw)
222
224
  _apply_fill(ax, xv, yv, series, i, spec, line.get_color())
223
225
  artists.append(line)
224
- apply_axis_scale(ax, "x", resolve_axis_scale(x_scale, x_log))
225
- apply_axis_scale(ax, "y", resolve_axis_scale(y_scale, y_log))
226
+ resolved_x_scale = resolve_axis_scale(x_scale, x_log)
227
+ resolved_y_scale = resolve_axis_scale(y_scale, y_log)
228
+ apply_axis_scale(ax, "x", resolved_x_scale)
229
+ apply_axis_scale(ax, "y", resolved_y_scale)
230
+ apply_tick_steps(ax, x_step, y_step, resolved_x_scale, resolved_y_scale)
226
231
  apply_tick_formats(ax, x_fmt, y_fmt)
227
232
  if title:
228
233
  ax.set_title(title)
@@ -242,9 +247,10 @@ def draw_series_axes(
242
247
  loc=st.legend_location,
243
248
  )
244
249
  if st.grid_alpha > 0:
245
- ax.grid(True, alpha=st.grid_alpha)
250
+ ax.grid(True, which="major", alpha=st.grid_alpha)
251
+ ax.grid(True, which="minor", alpha=st.grid_alpha * 0.4)
246
252
  else:
247
- ax.grid(False)
253
+ ax.grid(False, which="both")
248
254
  _apply_overrides(fig, ax, st, ov, n_series=len(series))
249
255
  return artists
250
256
 
@@ -270,6 +276,13 @@ def _render_impl(
270
276
  collect_map: bool = False,
271
277
  x_fmt: Mapping[str, Any] | None = None,
272
278
  y_fmt: Mapping[str, Any] | None = None,
279
+ x_step: float | None = None,
280
+ y_step: float | None = None,
281
+ y2_mask: Sequence[bool] | None = None,
282
+ y2_label: str = "",
283
+ y2_scale: str | None = None,
284
+ y2_fmt: Mapping[str, Any] | None = None,
285
+ y2_step: float | None = None,
273
286
  ) -> bytes | dict[str, Any]:
274
287
  """Render ``series`` (each ``(label, y)``) against ``x`` to image bytes.
275
288
 
@@ -295,7 +308,17 @@ def _render_impl(
295
308
  (MAIN #12) select linear/log/reciprocal; ``x_log``/``y_log`` are the
296
309
  back-compat boolean fallback (see :func:`draw_series_axes`'s doc).
297
310
  ``x_fmt``/``y_fmt`` (MAIN #24) are the tick-label number format -- see
298
- :func:`draw_series_axes`'s doc.
311
+ :func:`draw_series_axes`'s doc. ``y2_mask`` (parallel to ``series``,
312
+ ``True`` marks a channel drawn on a secondary/right Y axis) dispatches to
313
+ :func:`quantized.calc.figure_y2.render_with_secondary_axis` -- a real
314
+ ``Axes.twinx()`` -- instead of ``draw_series_axes``'s single axes;
315
+ ``None``/all-``False`` (the default) is today's single-axis behaviour,
316
+ byte-identical. ``y2_label``/``y2_scale``/``y2_fmt``/``y2_step`` mirror
317
+ their primary-axis counterparts but apply only to the secondary axis;
318
+ a fixed secondary range rides ``overrides["y2_lim"]`` (see
319
+ ``figure_y2.render_with_secondary_axis``'s doc). Not compatible with
320
+ ``x_breaks`` (raises ``ValueError``) -- a broken figure has several
321
+ axes already and gains no coherent secondary-axis meaning.
299
322
  """
300
323
  if fmt not in _FORMATS:
301
324
  raise ValueError(f"fmt must be one of {_FORMATS}")
@@ -307,11 +330,16 @@ def _render_impl(
307
330
  title = safe_mathtext_label(title)
308
331
  x_label = safe_mathtext_label(x_label)
309
332
  y_label = safe_mathtext_label(y_label)
333
+ y2_label = safe_mathtext_label(y2_label)
310
334
  series = [(safe_mathtext_label(label), y) for label, y in series]
311
335
  st = figure_style(style)
312
336
  ov = dict(overrides or {})
313
337
  _validate_overrides(ov)
314
338
  resolved_dpi = int(dpi) if dpi is not None else int(st.dpi)
339
+ y2_mask_list = list(y2_mask) if y2_mask is not None else [False] * len(series)
340
+ if len(y2_mask_list) != len(series):
341
+ raise ValueError("y2_mask must have the same length as series")
342
+ has_y2 = any(y2_mask_list)
315
343
 
316
344
  # rc_context scopes typography to this render (see style_rc). (matplotlib's
317
345
  # RcParams Literal-key type is impractical with the dynamic font.<generic>
@@ -321,6 +349,8 @@ def _render_impl(
321
349
 
322
350
  xv: NDArray[np.float64] = np.asarray(x, dtype=float)
323
351
  x_breaks = ov.get("x_breaks")
352
+ if has_y2 and x_breaks:
353
+ raise ValueError("y2_keys is not supported together with x_breaks")
324
354
  with matplotlib.rc_context(rc): # type: ignore[arg-type]
325
355
  # Manual axis breaks (gap #21): a distinct, twinned-panel rendering
326
356
  # path — not compatible with the hit-map collector (collect_map is
@@ -352,27 +382,47 @@ def _render_impl(
352
382
  series_styles=series_styles,
353
383
  x_fmt=x_fmt,
354
384
  y_fmt=y_fmt,
385
+ x_step=x_step,
386
+ y_step=y_step,
355
387
  )
356
388
  fig, ax = plt.subplots(figsize=figsize)
357
389
  try:
358
- artists = draw_series_axes(
359
- fig,
360
- ax,
361
- xv,
362
- series,
363
- st=st,
364
- ov=ov,
365
- x_log=x_log,
366
- y_log=y_log,
367
- x_scale=x_scale,
368
- y_scale=y_scale,
369
- title=title,
370
- x_label=x_label,
371
- y_label=y_label,
372
- series_styles=series_styles,
373
- x_fmt=x_fmt,
374
- y_fmt=y_fmt,
375
- )
390
+ if has_y2:
391
+ # Lazy import: mirrors figure_break's own lazy import above —
392
+ # keeps this module's own top-level import list light, and
393
+ # the twinx orchestration out of the 500-line ceiling here.
394
+ from quantized.calc.figure_y2 import render_with_secondary_axis
395
+
396
+ artists = render_with_secondary_axis(
397
+ fig, ax, xv, series, series_styles, y2_mask_list,
398
+ st=st, ov=ov, x_log=x_log, y_log=y_log,
399
+ x_scale=x_scale, y_scale=y_scale,
400
+ title=title, x_label=x_label, y_label=y_label,
401
+ x_fmt=x_fmt, y_fmt=y_fmt, x_step=x_step, y_step=y_step,
402
+ y2_label=y2_label, y2_scale=y2_scale,
403
+ y2_fmt=y2_fmt, y2_step=y2_step,
404
+ )
405
+ else:
406
+ artists = draw_series_axes(
407
+ fig,
408
+ ax,
409
+ xv,
410
+ series,
411
+ st=st,
412
+ ov=ov,
413
+ x_log=x_log,
414
+ y_log=y_log,
415
+ x_scale=x_scale,
416
+ y_scale=y_scale,
417
+ title=title,
418
+ x_label=x_label,
419
+ y_label=y_label,
420
+ series_styles=series_styles,
421
+ x_fmt=x_fmt,
422
+ y_fmt=y_fmt,
423
+ x_step=x_step,
424
+ y_step=y_step,
425
+ )
376
426
  if not ov.get("margins"):
377
427
  fig.tight_layout()
378
428
  if collect_map:
@@ -40,7 +40,7 @@ from numpy.typing import ArrayLike, NDArray # noqa: E402
40
40
 
41
41
  from quantized.calc.figure import _plot_kwargs # noqa: E402
42
42
  from quantized.calc.figure_scale import apply_axis_scale, resolve_axis_scale # noqa: E402
43
- from quantized.calc.figure_ticks import apply_tick_formats # noqa: E402
43
+ from quantized.calc.figure_ticks import apply_tick_formats, apply_tick_steps # noqa: E402
44
44
 
45
45
  __all__ = ["render_breaks_impl"]
46
46
 
@@ -65,6 +65,8 @@ def render_breaks_impl(
65
65
  series_styles: Sequence[Mapping[str, Any] | None] | None,
66
66
  x_fmt: Mapping[str, Any] | None = None,
67
67
  y_fmt: Mapping[str, Any] | None = None,
68
+ x_step: float | None = None,
69
+ y_step: float | None = None,
68
70
  ) -> bytes:
69
71
  """Render ``series`` against ``x`` with the x-axis elided over each
70
72
  ``[lo, hi]`` pair in ``breaks`` (already sorted/validated non-overlapping
@@ -100,8 +102,11 @@ def render_breaks_impl(
100
102
  ax.plot(x, np.asarray(y, dtype=float), label=label, **kw)
101
103
  lo, hi = bounds[i]
102
104
  ax.set_xlim(lo, hi)
103
- apply_axis_scale(ax, "x", resolve_axis_scale(x_scale, x_log))
104
- apply_axis_scale(ax, "y", resolve_axis_scale(y_scale, y_log))
105
+ resolved_x_scale = resolve_axis_scale(x_scale, x_log)
106
+ resolved_y_scale = resolve_axis_scale(y_scale, y_log)
107
+ apply_axis_scale(ax, "x", resolved_x_scale)
108
+ apply_axis_scale(ax, "y", resolved_y_scale)
109
+ apply_tick_steps(ax, x_step, y_step, resolved_x_scale, resolved_y_scale)
105
110
  apply_tick_formats(ax, x_fmt, y_fmt)
106
111
  if i == 0:
107
112
  handles, labels_out = ax.get_legend_handles_labels()
@@ -113,7 +118,8 @@ def render_breaks_impl(
113
118
  if not st.box_on:
114
119
  ax.spines["top"].set_visible(False)
115
120
  if st.grid_alpha > 0:
116
- ax.grid(True, alpha=st.grid_alpha)
121
+ ax.grid(True, which="major", alpha=st.grid_alpha)
122
+ ax.grid(True, which="minor", alpha=st.grid_alpha * 0.4)
117
123
 
118
124
  # Diagonal break glyphs (matplotlib's standard broken-axis recipe):
119
125
  # short strokes angled across each seam, on both the outgoing panel's
@@ -28,6 +28,44 @@ __all__ = ["render_categorical_figure"]
28
28
  _FORMATS = ("pdf", "svg", "png", "tiff")
29
29
 
30
30
 
31
+ def _draw_categorical_bars(
32
+ ax: Any,
33
+ groups: list[str],
34
+ series: list[str],
35
+ vals: Any,
36
+ errs: Any | None,
37
+ stacked: bool,
38
+ ) -> None:
39
+ """Draw one grouped/stacked bar panel into `ax` — shared by the flat
40
+ single-panel path below and `figure_facets.render_categorical_facets_figure`
41
+ (GUI_INTERACTION #12 slice 4b), so a faceted panel matches the flat
42
+ export exactly. Caller applies title/axis-labels/spines/legend/grid —
43
+ this function only draws the bars + category ticks + zero baseline."""
44
+ n_groups, n_series = len(groups), len(series)
45
+ x = np.arange(n_groups, dtype=float)
46
+ if stacked:
47
+ bottom = np.zeros(n_groups)
48
+ for si in range(n_series):
49
+ yerr = errs[:, si] if errs is not None and si == n_series - 1 else None
50
+ ax.bar(
51
+ x, vals[:, si], 0.68, bottom=bottom, yerr=yerr, capsize=3,
52
+ label=series[si],
53
+ )
54
+ bottom = bottom + np.nan_to_num(vals[:, si])
55
+ else:
56
+ width = 0.8 / n_series
57
+ for si in range(n_series):
58
+ offset = (si - (n_series - 1) / 2) * width
59
+ yerr = errs[:, si] if errs is not None else None
60
+ ax.bar(
61
+ x + offset, vals[:, si], width * 0.85, yerr=yerr, capsize=3,
62
+ label=series[si],
63
+ )
64
+ ax.set_xticks(x)
65
+ ax.set_xticklabels(groups)
66
+ ax.axhline(0, color="0.3", linewidth=0.8) # baseline, visible for mixed-sign data
67
+
68
+
31
69
  def _to_matrix(
32
70
  values: list[list[float]], n_groups: int, n_series: int, name: str
33
71
  ) -> np.ndarray:
@@ -111,28 +149,7 @@ def render_categorical_figure(
111
149
  with matplotlib.rc_context(rc): # type: ignore[arg-type]
112
150
  fig, ax = plt.subplots(figsize=figsize)
113
151
  try:
114
- x = np.arange(n_groups, dtype=float)
115
- if stacked:
116
- bottom = np.zeros(n_groups)
117
- for si in range(n_series):
118
- yerr = errs[:, si] if errs is not None and si == n_series - 1 else None
119
- ax.bar(
120
- x, vals[:, si], 0.68, bottom=bottom, yerr=yerr, capsize=3,
121
- label=series[si],
122
- )
123
- bottom = bottom + np.nan_to_num(vals[:, si])
124
- else:
125
- width = 0.8 / n_series
126
- for si in range(n_series):
127
- offset = (si - (n_series - 1) / 2) * width
128
- yerr = errs[:, si] if errs is not None else None
129
- ax.bar(
130
- x + offset, vals[:, si], width * 0.85, yerr=yerr, capsize=3,
131
- label=series[si],
132
- )
133
- ax.set_xticks(x)
134
- ax.set_xticklabels(groups)
135
- ax.axhline(0, color="0.3", linewidth=0.8) # baseline, visible for mixed-sign data
152
+ _draw_categorical_bars(ax, groups, series, vals, errs, stacked)
136
153
  if title:
137
154
  ax.set_title(title)
138
155
  if x_label: