plothist 1.5.0__tar.gz → 1.7.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 (180) hide show
  1. {plothist-1.5.0 → plothist-1.7.0}/.github/workflows/cd.yaml +3 -3
  2. {plothist-1.5.0 → plothist-1.7.0}/.github/workflows/ci.yaml +1 -1
  3. {plothist-1.5.0 → plothist-1.7.0}/.github/workflows/coverage.yaml +1 -1
  4. {plothist-1.5.0 → plothist-1.7.0}/.github/workflows/pr.yaml +1 -1
  5. {plothist-1.5.0 → plothist-1.7.0}/.gitignore +1 -0
  6. {plothist-1.5.0 → plothist-1.7.0}/.pre-commit-config.yaml +7 -7
  7. plothist-1.7.0/AUTHORS.md +2 -0
  8. plothist-1.7.0/CONTRIBUTING.md +1 -0
  9. {plothist-1.5.0 → plothist-1.7.0}/PKG-INFO +1 -1
  10. {plothist-1.5.0 → plothist-1.7.0}/codecov.yml +0 -3
  11. {plothist-1.5.0 → plothist-1.7.0}/docs/basics/variable_registry.rst +17 -19
  12. {plothist-1.5.0 → plothist-1.7.0}/docs/conf.py +3 -5
  13. plothist-1.7.0/docs/documentation/statistics.rst +21 -0
  14. plothist-1.7.0/docs/img/2d_hist_correlations_0.png +0 -0
  15. plothist-1.7.0/docs/img/2d_hist_correlations_1.png +0 -0
  16. plothist-1.7.0/docs/img/2d_hist_correlations_2.png +0 -0
  17. plothist-1.7.0/docs/img/model_all_comparisons.png +0 -0
  18. plothist-1.7.0/docs/img/model_all_comparisons_no_model_unc.png +0 -0
  19. plothist-1.7.0/docs/img/model_examples_pull.png +0 -0
  20. {plothist-1.5.0 → plothist-1.7.0}/docs/img/model_examples_pull_no_model_unc.png +0 -0
  21. plothist-1.7.0/docs/img/model_examples_stacked.png +0 -0
  22. plothist-1.7.0/docs/img/model_examples_stacked_unstacked.png +0 -0
  23. plothist-1.7.0/docs/img/model_examples_unstacked.png +0 -0
  24. {plothist-1.5.0 → plothist-1.7.0}/docs/img/ratio_data_vs_model_with_stacked_and_unstacked_function_components.png +0 -0
  25. plothist-1.7.0/docs/img/uncertainty_types.png +0 -0
  26. {plothist-1.5.0 → plothist-1.7.0}/docs/usage/installation.rst +2 -2
  27. {plothist-1.5.0 → plothist-1.7.0}/pyproject.toml +4 -2
  28. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/__init__.py +8 -11
  29. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/_version.py +16 -3
  30. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/comparison.py +61 -17
  31. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/2d_hist/2d_hist_correlations.py +2 -2
  32. plothist-1.7.0/src/plothist/examples/utility/uncertainty_types.py +120 -0
  33. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/histogramming.py +8 -2
  34. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/plothist_style.py +2 -2
  35. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/plotters.py +3 -1
  36. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/variable_registry.py +32 -9
  37. {plothist-1.5.0 → plothist-1.7.0}/tests/test_boost_histogram_version.py +1 -1
  38. {plothist-1.5.0 → plothist-1.7.0}/tests/test_comparison.py +14 -4
  39. {plothist-1.5.0 → plothist-1.7.0}/tests/test_comparison_efficiency.py +1 -1
  40. {plothist-1.5.0 → plothist-1.7.0}/tests/test_histogramming.py +17 -9
  41. {plothist-1.5.0 → plothist-1.7.0}/tests/test_plothist_style.py +7 -7
  42. {plothist-1.5.0 → plothist-1.7.0}/tests/test_plotters.py +11 -9
  43. {plothist-1.5.0 → plothist-1.7.0}/tests/test_variable_registry.py +121 -22
  44. plothist-1.5.0/AUTHORS.md +0 -2
  45. plothist-1.5.0/docs/documentation/statistics.rst +0 -14
  46. plothist-1.5.0/docs/img/2d_hist_correlations_0.png +0 -0
  47. plothist-1.5.0/docs/img/2d_hist_correlations_1.png +0 -0
  48. plothist-1.5.0/docs/img/2d_hist_correlations_2.png +0 -0
  49. plothist-1.5.0/docs/img/model_all_comparisons.png +0 -0
  50. plothist-1.5.0/docs/img/model_all_comparisons_no_model_unc.png +0 -0
  51. plothist-1.5.0/docs/img/model_examples_pull.png +0 -0
  52. plothist-1.5.0/docs/img/model_examples_stacked.png +0 -0
  53. plothist-1.5.0/docs/img/model_examples_stacked_unstacked.png +0 -0
  54. plothist-1.5.0/docs/img/model_examples_unstacked.png +0 -0
  55. {plothist-1.5.0 → plothist-1.7.0}/.github/ISSUE_TEMPLATE/user-story.md +0 -0
  56. {plothist-1.5.0 → plothist-1.7.0}/.github/dependabot.yaml +0 -0
  57. {plothist-1.5.0 → plothist-1.7.0}/.github/release.yaml +0 -0
  58. {plothist-1.5.0 → plothist-1.7.0}/.readthedocs.yaml +0 -0
  59. {plothist-1.5.0 → plothist-1.7.0}/CITATION.cff +0 -0
  60. {plothist-1.5.0 → plothist-1.7.0}/LICENSE +0 -0
  61. {plothist-1.5.0 → plothist-1.7.0}/README.rst +0 -0
  62. {plothist-1.5.0 → plothist-1.7.0}/docs/CONTRIBUTING.rst +0 -0
  63. {plothist-1.5.0 → plothist-1.7.0}/docs/advanced/model_examples.rst +0 -0
  64. {plothist-1.5.0 → plothist-1.7.0}/docs/advanced/other_advanced.rst +0 -0
  65. {plothist-1.5.0 → plothist-1.7.0}/docs/basics/1d_func.rst +0 -0
  66. {plothist-1.5.0 → plothist-1.7.0}/docs/basics/1d_hist.rst +0 -0
  67. {plothist-1.5.0 → plothist-1.7.0}/docs/basics/2d_hist.rst +0 -0
  68. {plothist-1.5.0 → plothist-1.7.0}/docs/documentation/documentation.rst +0 -0
  69. {plothist-1.5.0 → plothist-1.7.0}/docs/documentation/troubleshooting.rst +0 -0
  70. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_advanced.png +0 -0
  71. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_advanced.svg +0 -0
  72. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_asymmetry.png +0 -0
  73. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_difference.png +0 -0
  74. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_efficiency.png +0 -0
  75. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_only_efficiency.png +0 -0
  76. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_pull.png +0 -0
  77. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_ratio.png +0 -0
  78. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_relative_difference.png +0 -0
  79. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_comparison_split_ratio.png +0 -0
  80. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_elt1.png +0 -0
  81. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_elt1_stacked.png +0 -0
  82. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_elt2.png +0 -0
  83. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_hist_simple.png +0 -0
  84. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_int_category.png +0 -0
  85. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_profile.png +0 -0
  86. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_side_by_side.png +0 -0
  87. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_side_by_side_with_numbers.png +0 -0
  88. {plothist-1.5.0 → plothist-1.7.0}/docs/img/1d_str_category.png +0 -0
  89. {plothist-1.5.0 → plothist-1.7.0}/docs/img/2d_hist_simple.png +0 -0
  90. {plothist-1.5.0 → plothist-1.7.0}/docs/img/2d_hist_simple_discrete_colormap.png +0 -0
  91. {plothist-1.5.0 → plothist-1.7.0}/docs/img/2d_hist_uneven.png +0 -0
  92. {plothist-1.5.0 → plothist-1.7.0}/docs/img/2d_hist_with_projections.png +0 -0
  93. {plothist-1.5.0 → plothist-1.7.0}/docs/img/2d_hist_with_projections.svg +0 -0
  94. {plothist-1.5.0 → plothist-1.7.0}/docs/img/add_text_example.png +0 -0
  95. {plothist-1.5.0 → plothist-1.7.0}/docs/img/asymmetry_comparison_advanced.png +0 -0
  96. {plothist-1.5.0 → plothist-1.7.0}/docs/img/color_palette_hists.png +0 -0
  97. {plothist-1.5.0 → plothist-1.7.0}/docs/img/fct_1d.png +0 -0
  98. {plothist-1.5.0 → plothist-1.7.0}/docs/img/fct_1d_stacked.png +0 -0
  99. {plothist-1.5.0 → plothist-1.7.0}/docs/img/matplotlib_example.png +0 -0
  100. {plothist-1.5.0 → plothist-1.7.0}/docs/img/model_examples_flatten2D.png +0 -0
  101. {plothist-1.5.0 → plothist-1.7.0}/docs/img/model_examples_stacked.svg +0 -0
  102. {plothist-1.5.0 → plothist-1.7.0}/docs/img/model_with_stacked_and_unstacked_function_components.png +0 -0
  103. {plothist-1.5.0 → plothist-1.7.0}/docs/img/model_with_stacked_and_unstacked_histograms_components.png +0 -0
  104. {plothist-1.5.0 → plothist-1.7.0}/docs/img/plothist_example.png +0 -0
  105. {plothist-1.5.0 → plothist-1.7.0}/docs/img/pyhf_example.svg +0 -0
  106. {plothist-1.5.0 → plothist-1.7.0}/docs/img/savefig_comparisons.gif +0 -0
  107. {plothist-1.5.0 → plothist-1.7.0}/docs/img/usage_YlGnBu_r_palette.png +0 -0
  108. {plothist-1.5.0 → plothist-1.7.0}/docs/img/usage_coolwarm_palette.png +0 -0
  109. {plothist-1.5.0 → plothist-1.7.0}/docs/img/usage_cubehelix.png +0 -0
  110. {plothist-1.5.0 → plothist-1.7.0}/docs/img/usage_style_cycle.png +0 -0
  111. {plothist-1.5.0 → plothist-1.7.0}/docs/img/usage_viridis_palette.png +0 -0
  112. {plothist-1.5.0 → plothist-1.7.0}/docs/index.rst +0 -0
  113. {plothist-1.5.0 → plothist-1.7.0}/docs/usage/plot_fitting_results.rst +0 -0
  114. {plothist-1.5.0 → plothist-1.7.0}/docs/usage/style.rst +0 -0
  115. {plothist-1.5.0 → plothist-1.7.0}/docs/usage/utilities.rst +0 -0
  116. {plothist-1.5.0 → plothist-1.7.0}/noxfile.py +0 -0
  117. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/_version.pyi +0 -0
  118. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/default_style.mplstyle +0 -0
  119. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_asymmetry.py +0 -0
  120. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_difference.py +0 -0
  121. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_efficiency.py +0 -0
  122. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_only_efficiency.py +0 -0
  123. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_pull.py +0 -0
  124. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_ratio.py +0 -0
  125. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_relative_difference.py +0 -0
  126. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_comparison_split_ratio.py +0 -0
  127. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_elt1.py +0 -0
  128. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_elt1_stacked.py +0 -0
  129. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_elt2.py +0 -0
  130. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_hist_simple.py +0 -0
  131. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_int_category.py +0 -0
  132. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_profile.py +0 -0
  133. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_side_by_side.py +0 -0
  134. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/1d_str_category.py +0 -0
  135. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/1d_hist/README.rst +0 -0
  136. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/2d_hist/2d_hist_simple.py +0 -0
  137. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/2d_hist/2d_hist_simple_discrete_colormap.py +0 -0
  138. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/2d_hist/2d_hist_uneven.py +0 -0
  139. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/2d_hist/2d_hist_with_projections.py +0 -0
  140. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/2d_hist/README.rst +0 -0
  141. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/README.rst +0 -0
  142. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/advanced/1d_comparison_advanced.py +0 -0
  143. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/advanced/1d_side_by_side_with_numbers.py +0 -0
  144. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/advanced/README.rst +0 -0
  145. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/advanced/asymmetry_comparison_advanced.py +0 -0
  146. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/advanced/model_examples_flatten2D.py +0 -0
  147. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/func_1d/README.rst +0 -0
  148. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/func_1d/fct_1d.py +0 -0
  149. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/func_1d/fct_1d_stacked.py +0 -0
  150. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/README.rst +0 -0
  151. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_all_comparisons.py +0 -0
  152. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_all_comparisons_no_model_unc.py +0 -0
  153. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_examples_pull.py +0 -0
  154. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_examples_pull_no_model_unc.py +0 -0
  155. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_examples_stacked.py +0 -0
  156. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_examples_stacked_unstacked.py +0 -0
  157. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_examples_unstacked.py +0 -0
  158. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_with_stacked_and_unstacked_function_components.py +0 -0
  159. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py +0 -0
  160. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py +0 -0
  161. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/utility/README.rst +0 -0
  162. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/utility/add_text_example.py +0 -0
  163. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/utility/color_palette_hists.py +0 -0
  164. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/utility/color_palette_squares.py +0 -0
  165. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/examples/utility/matplotlib_vs_plothist_style.py +0 -0
  166. {plothist-1.5.0 → plothist-1.7.0}/src/plothist/test_helpers.py +0 -0
  167. {plothist-1.5.0 → plothist-1.7.0}/tests/test_comparison_asymmetry.py +0 -0
  168. {plothist-1.5.0 → plothist-1.7.0}/tests/test_comparison_difference.py +0 -0
  169. {plothist-1.5.0 → plothist-1.7.0}/tests/test_comparison_pull.py +0 -0
  170. {plothist-1.5.0 → plothist-1.7.0}/tests/test_comparison_ratio.py +0 -0
  171. {plothist-1.5.0 → plothist-1.7.0}/tests/test_examples_1d_hist.py +0 -0
  172. {plothist-1.5.0 → plothist-1.7.0}/tests/test_examples_2d_hist.py +0 -0
  173. {plothist-1.5.0 → plothist-1.7.0}/tests/test_examples_advanced.py +0 -0
  174. {plothist-1.5.0 → plothist-1.7.0}/tests/test_examples_data_model.py +0 -0
  175. {plothist-1.5.0 → plothist-1.7.0}/tests/test_examples_func_1d.py +0 -0
  176. {plothist-1.5.0 → plothist-1.7.0}/tests/test_examples_utility.py +0 -0
  177. {plothist-1.5.0 → plothist-1.7.0}/tests/test_fonts.py +0 -0
  178. {plothist-1.5.0 → plothist-1.7.0}/tests/test_get_data.py +0 -0
  179. {plothist-1.5.0 → plothist-1.7.0}/tests/test_test_helpers.py +0 -0
  180. {plothist-1.5.0 → plothist-1.7.0}/uv.lock +0 -0
@@ -15,7 +15,7 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
 
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v5
19
19
  with:
20
20
  persist-credentials: false
21
21
  - name: Install uv and set the python version
@@ -46,7 +46,7 @@ jobs:
46
46
 
47
47
  steps:
48
48
  - name: Download all the dists
49
- uses: actions/download-artifact@v4
49
+ uses: actions/download-artifact@v5
50
50
  with:
51
51
  name: python-package-distributions
52
52
  path: dist/
@@ -71,7 +71,7 @@ jobs:
71
71
 
72
72
  steps:
73
73
  - name: Download all the dists
74
- uses: actions/download-artifact@v4
74
+ uses: actions/download-artifact@v5
75
75
  with:
76
76
  name: python-package-distributions
77
77
  path: dist/
@@ -16,7 +16,7 @@ jobs:
16
16
  python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
17
17
 
18
18
  steps:
19
- - uses: actions/checkout@v4
19
+ - uses: actions/checkout@v5
20
20
 
21
21
  - name: Install uv and set the python version
22
22
  uses: astral-sh/setup-uv@v6
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - name: Checkout
14
- uses: actions/checkout@v4
14
+ uses: actions/checkout@v5
15
15
  with:
16
16
  fetch-depth: 2
17
17
 
@@ -16,6 +16,6 @@ jobs:
16
16
  name: Validate PR title
17
17
  runs-on: ubuntu-latest
18
18
  steps:
19
- - uses: amannn/action-semantic-pull-request@v5
19
+ - uses: amannn/action-semantic-pull-request@v6
20
20
  env:
21
21
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -15,6 +15,7 @@ temp_img/
15
15
  html/
16
16
  sg_execution_times.rst
17
17
  docs/examples/*/*.svg
18
+ src/plothist/examples/*/*.svg
18
19
  example_gallery/
19
20
  .svg_metadata.yaml
20
21
  tests/*.yaml
@@ -5,7 +5,7 @@ ci:
5
5
 
6
6
  repos:
7
7
  - repo: https://github.com/adamchainz/blacken-docs
8
- rev: "1.19.1"
8
+ rev: "1.20.0"
9
9
  hooks:
10
10
  - id: blacken-docs
11
11
  args: ["--line-length", "120"]
@@ -13,7 +13,7 @@ repos:
13
13
  - black==24.2.0
14
14
 
15
15
  - repo: https://github.com/pre-commit/pre-commit-hooks
16
- rev: v5.0.0
16
+ rev: v6.0.0
17
17
  hooks:
18
18
  - id: check-added-large-files
19
19
  - id: check-case-conflict
@@ -30,7 +30,7 @@ repos:
30
30
  args: ["--pytest-test-first"]
31
31
 
32
32
  - repo: https://github.com/astral-sh/ruff-pre-commit
33
- rev: v0.12.2
33
+ rev: v0.13.3
34
34
  hooks:
35
35
  - id: ruff
36
36
  args: ["--fix", "--show-fixes"]
@@ -44,13 +44,13 @@ repos:
44
44
  - tomli
45
45
 
46
46
  - repo: https://github.com/python-jsonschema/check-jsonschema
47
- rev: 0.33.2
47
+ rev: 0.34.0
48
48
  hooks:
49
49
  - id: check-github-workflows
50
50
  args: ["--verbose"]
51
51
 
52
52
  - repo: https://github.com/pre-commit/mirrors-mypy
53
- rev: v1.16.1
53
+ rev: v1.18.2
54
54
  hooks:
55
55
  - id: mypy
56
56
  files: src
@@ -66,13 +66,13 @@ repos:
66
66
  - id: rst-inline-touching-normal
67
67
 
68
68
  - repo: https://github.com/python-jsonschema/check-jsonschema
69
- rev: 0.33.2
69
+ rev: 0.34.0
70
70
  hooks:
71
71
  - id: check-readthedocs
72
72
  - id: check-dependabot
73
73
  - id: check-github-workflows
74
74
 
75
75
  - repo: https://github.com/henryiii/validate-pyproject-schema-store
76
- rev: 2025.06.23
76
+ rev: 2025.10.03
77
77
  hooks:
78
78
  - id: validate-pyproject
@@ -0,0 +1,2 @@
1
+ * Cyrille Praz ([@cyrraz](https://github.com/cyrraz))
2
+ * Tristan Fillinger ([@0ctagon](https://github.com/0ctagon))
@@ -0,0 +1 @@
1
+ For contributing, refer to the chapter [Contributing](https://plothist.readthedocs.io/en/latest/CONTRIBUTING.html) in the documentation.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plothist
3
- Version: 1.5.0
3
+ Version: 1.7.0
4
4
  Summary: Plot histograms in a scalable way and a beautiful style.
5
5
  Project-URL: Homepage, https://github.com/cyrraz/plothist
6
6
  Project-URL: Documentation, https://plothist.readthedocs.io/
@@ -1,6 +1,3 @@
1
1
  comment: false
2
2
 
3
3
  github_checks: false
4
-
5
- ignore:
6
- - "src/plothist/scripts"
@@ -25,7 +25,7 @@ For each variable in the list, the following information is stored by default in
25
25
 
26
26
  variable_0:
27
27
  name: variable_0
28
- bins: 50
28
+ bins: auto
29
29
  range:
30
30
  - min
31
31
  - max
@@ -63,24 +63,24 @@ Update the registry
63
63
 
64
64
  Multiple functions are available to modify the plotting information of the variables in the registry, add or remove some parameters.
65
65
 
66
- Ranges
67
- ------
66
+ Binning and ranges
67
+ ------------------
68
68
 
69
- The :func:`update_variable_registry_ranges() <plothist.variable_registry.update_variable_registry_ranges>` function automatically updates the range parameter in the ``yaml`` file to the ``min`` and ``max`` values of the variable in the dataset:
69
+ The :func:`update_variable_registry_binning() <plothist.variable_registry.update_variable_registry_binning>` function automatically updates the number of bins parameter in the ``yaml`` file to the length of [``numpy.histogram_bin_edges``](https://numpy.org/doc/2.1/reference/generated/numpy.histogram_bin_edges.html#numpy-histogram-bin-edges) minus one (the bins are regular) and automatically updates the range parameter in the ``yaml`` file to the ``min`` and ``max`` values of the variable in the dataset:
70
70
 
71
71
  .. code-block:: python
72
72
 
73
- from plothist import update_variable_registry_ranges
73
+ from plothist import update_variable_registry_binning
74
74
 
75
- update_variable_registry_ranges(df, variable_keys)
75
+ update_variable_registry_binning(df, variable_keys)
76
76
 
77
- The range has been updated for all the variables in ``variables_keys``. The ``yaml`` file is now:
77
+ The number of bins and the range has been updated for all the variables in ``variables_keys``. The ``yaml`` file is now:
78
78
 
79
79
  .. code-block:: yaml
80
80
 
81
81
  variable_0:
82
82
  name: variable_0
83
- bins: 50
83
+ bins: 121 # = len(numpy.histogram_bin_edges(df["variable_0"], bins="auto")) - 1
84
84
  range:
85
85
  - -10.55227774892869 # min(df["variable_0"])
86
86
  - 10.04658448558009 # max(df["variable_0"])
@@ -94,10 +94,9 @@ The range has been updated for all the variables in ``variables_keys``. The ``ya
94
94
  variable_1:
95
95
  ...
96
96
 
97
- Then, you may manually modify the ``yaml`` to get a more suitable range to display in the plot.
98
-
99
- Calling this function again on the same variable keys will not overwrite their ``range`` parameter, unless the ``overwrite`` parameter is set to ``True``.
97
+ Then, you may manually modify the ``yaml`` to get a more suitable binning and range to display in the plot.
100
98
 
99
+ Calling this function again on the same variable keys will not overwrite their ``bins`` or ``range`` parameter, unless the ``overwrite`` parameter is set to ``True``.
101
100
 
102
101
  Add or modify variable properties
103
102
  ---------------------------------
@@ -124,7 +123,7 @@ This will add the new properties to the ``yaml`` file to all the variables in ``
124
123
 
125
124
  variable_0:
126
125
  name: variable_0
127
- bins: 50
126
+ bins: 121
128
127
  range:
129
128
  - -10.55227774892869
130
129
  - 10.04658448558009
@@ -160,7 +159,7 @@ To remove a parameter from the plotting information, you can use the :func:`remo
160
159
 
161
160
  from plothist import remove_variable_registry_parameters
162
161
 
163
- remove_variable_registry_parameters(["range", "log", "legend_ncols", "new_property"], variable_keys)
162
+ remove_variable_registry_parameters(["bins", "range", "log", "legend_ncols", "new_property"], variable_keys)
164
163
 
165
164
  The ``yaml`` file is updated:
166
165
 
@@ -168,7 +167,6 @@ The ``yaml`` file is updated:
168
167
 
169
168
  variable_0:
170
169
  name: variable_0
171
- bins: 50
172
170
  label: variable_0
173
171
  legend_location: best
174
172
  docstring: ''
@@ -197,7 +195,7 @@ Here is an example of how to create, update, and use the variable registry to pl
197
195
  plot_hist,
198
196
  create_variable_registry,
199
197
  update_variable_registry,
200
- update_variable_registry_ranges,
198
+ update_variable_registry_binning,
201
199
  get_variable_from_registry,
202
200
  add_text,
203
201
  )
@@ -208,8 +206,8 @@ Here is an example of how to create, update, and use the variable registry to pl
208
206
  # Create the registry
209
207
  create_variable_registry(variable_keys)
210
208
 
211
- # Update the ranges
212
- update_variable_registry_ranges(df, variable_keys)
209
+ # Update the number of bins and range
210
+ update_variable_registry_binning(df, variable_keys)
213
211
 
214
212
  # Add custom info
215
213
  update_variable_registry({"text": "my analysis"}, variable_keys)
@@ -245,7 +243,7 @@ Example: to plot a zoom on a variable but still keep the original one, you can c
245
243
 
246
244
  variable_0:
247
245
  name: variable_0
248
- bins: 50
246
+ bins: 121
249
247
  range:
250
248
  - -10
251
249
  - 10
@@ -257,7 +255,7 @@ Example: to plot a zoom on a variable but still keep the original one, you can c
257
255
 
258
256
  variable_0_zoom:
259
257
  name: variable_0
260
- bins: 50
258
+ bins: 121
261
259
  range:
262
260
  - -1
263
261
  - 1
@@ -1,5 +1,8 @@
1
1
  import sys
2
2
 
3
+ from sphinx_gallery.scrapers import matplotlib_scraper
4
+ from sphinx_gallery.sorting import ExplicitOrder
5
+
3
6
  import plothist
4
7
 
5
8
  #
@@ -175,9 +178,6 @@ def reset_mpl(gallery_conf, fname):
175
178
  set_style("default")
176
179
 
177
180
 
178
- from sphinx_gallery.scrapers import matplotlib_scraper
179
-
180
-
181
181
  class matplotlib_svg_scraper:
182
182
  def __repr__(self):
183
183
  return self.__class__.__name__
@@ -186,8 +186,6 @@ class matplotlib_svg_scraper:
186
186
  return matplotlib_scraper(*args, format="svg", bbox_inches="tight", **kwargs)
187
187
 
188
188
 
189
- from sphinx_gallery.sorting import ExplicitOrder
190
-
191
189
  sphinx_gallery_conf = {
192
190
  # path to your example scripts
193
191
  "examples_dirs": ["../src/plothist/examples"],
@@ -0,0 +1,21 @@
1
+ .. _documentation-statistics-label:
2
+
3
+ ===================
4
+ Notes on statistics
5
+ ===================
6
+
7
+ In the :func:`plot_error_hist() <plothist.plotters.plot_error_hist>` function, the represented uncertainties can be:
8
+
9
+ - ``symmetrical``: use the square root of the variance of the histogram
10
+ - ``asymmetrical``: frequentist approach based on a Poisson confidence interval (see `page 16 on this presentation <https://www.nikhef.nl/~ivov/Statistics/PoissonError/2017_05_15_PoissonError_LHCb_IvovanVulpen.pdf>`_)
11
+
12
+ - the upper limit on bins with no entries can be interpreted differently. By default, a one-sided 68% confidence bound is used. The behavior can be changed using the ``uncertainty_type = asymmetrical_double_sided_zeros``, which will use a two-sided 68% confidence bound.
13
+ - this method doesn't support weighted histograms. For more details, see the `note about uncertainties when the histogram entries are weighted <https://www.pp.rhul.ac.uk/~cowan/stat/notes/errors_with_weights.pdf>`_.
14
+
15
+ .. image:: ../img/uncertainty_types.png
16
+ :alt: Simple error hist
17
+ :width: 500
18
+
19
+ The uncertainty on the efficiency (ratio of two histograms h1 and h2 when the entries of h1 are a subset of the entries of h2) in :func:`get_efficiency() <plothist.comparison.get_efficiency>` is calculated following equation (19) of:
20
+
21
+ - `T. Ullrich, Z. Xu, Treatment of Errors in Efficiency Calculations, arxiv: 0701199v1. <https://arxiv.org/pdf/physics/0701199v1.pdf>`_
@@ -64,11 +64,11 @@ To update ``plothist`` to its latest stable version, follow the instructions abo
64
64
  Install the development version
65
65
  ===============================
66
66
 
67
- 1. Clone the plothist repository and go to the package folder:
67
+ 1. `Fork <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo?tool=webui>`_ and clone locally the plothist repository, then go to the package folder:
68
68
 
69
69
  .. code-block:: bash
70
70
 
71
- git clone git@github.com:cyrraz/plothist.git
71
+ git clone git@github.com:USERNAME/plothist.git
72
72
 
73
73
  cd plothist
74
74
 
@@ -83,7 +83,9 @@ extend-select = [
83
83
  "PD", # pandas-vet
84
84
  ]
85
85
  ignore = [
86
- "E402", # module level import not at top of file
87
86
  "NPY002", # Replace legacy `np.random` call with `np.random.Generator`
88
- "PD901", # Avoid using the generic variable name `df` for DataFrames
87
+ ]
88
+ [tool.ruff.lint.per-file-ignores]
89
+ "src/plothist/examples/**/*.py" = [
90
+ "E402", # module level import not at top of file
89
91
  ]
@@ -9,12 +9,7 @@ from .comparison import (
9
9
  get_ratio,
10
10
  get_ratio_variances,
11
11
  )
12
- from .histogramming import (
13
- create_axis,
14
- flatten_2d_hist,
15
- make_2d_hist,
16
- make_hist,
17
- )
12
+ from .histogramming import create_axis, flatten_2d_hist, make_2d_hist, make_hist
18
13
  from .plothist_style import (
19
14
  add_luminosity,
20
15
  add_text,
@@ -43,6 +38,7 @@ from .variable_registry import (
43
38
  get_variable_from_registry,
44
39
  remove_variable_registry_parameters,
45
40
  update_variable_registry,
41
+ update_variable_registry_binning,
46
42
  update_variable_registry_ranges,
47
43
  )
48
44
 
@@ -81,22 +77,24 @@ __all__ = [
81
77
  "set_fitting_ylabel_fontsize",
82
78
  "set_style",
83
79
  "update_variable_registry",
80
+ "update_variable_registry_binning",
84
81
  "update_variable_registry_ranges",
85
82
  ]
86
83
 
87
84
 
88
- # Get style file and use it
85
+ from importlib import resources
89
86
  from importlib.resources import files
90
87
 
88
+ import boost_histogram as bh
89
+ import matplotlib.font_manager as fm
91
90
  import matplotlib.pyplot as plt
92
91
 
92
+ # Get style file and use it
93
+
93
94
  style_file = files("plothist").joinpath("default_style.mplstyle")
94
95
  plt.style.use(style_file)
95
96
 
96
97
  # Install fonts
97
- from importlib import resources
98
-
99
- import matplotlib.font_manager as fm
100
98
 
101
99
  with resources.as_file(resources.files("plothist_utils") / "fonts") as font_path:
102
100
  font_files = fm.findSystemFonts(fontpaths=[str(font_path)])
@@ -104,7 +102,6 @@ with resources.as_file(resources.files("plothist_utils") / "fonts") as font_path
104
102
  fm.fontManager.addfont(font)
105
103
 
106
104
  # Check version of boost_histogram
107
- import boost_histogram as bh
108
105
 
109
106
  if tuple(int(part) for part in bh.__version__.split(".")) < (1, 4, 0):
110
107
  raise ImportError(
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '1.5.0'
21
- __version_tuple__ = version_tuple = (1, 5, 0)
31
+ __version__ = version = '1.7.0'
32
+ __version_tuple__ = version_tuple = (1, 7, 0)
33
+
34
+ __commit_id__ = commit_id = None
@@ -22,9 +22,16 @@ def _check_uncertainty_type(uncertainty_type: str) -> None:
22
22
  If the uncertainty type is not valid.
23
23
 
24
24
  """
25
- if uncertainty_type not in ["symmetrical", "asymmetrical"]:
25
+ _valid_uncertainty_types = [
26
+ "symmetrical",
27
+ "asymmetrical",
28
+ "asymmetrical_double_sided_zeros",
29
+ "asymmetrical_one_sided_zeros",
30
+ ]
31
+
32
+ if uncertainty_type not in _valid_uncertainty_types:
26
33
  raise ValueError(
27
- f"Uncertainty type {uncertainty_type} not valid. Must be 'symmetrical' or 'asymmetrical'."
34
+ f"Uncertainty type {uncertainty_type} not valid. Must be in {_valid_uncertainty_types}."
28
35
  )
29
36
 
30
37
 
@@ -42,11 +49,12 @@ def _is_unweighted(hist: bh.Histogram) -> bool:
42
49
  bool
43
50
  True if the histogram is unweighted, False otherwise.
44
51
  """
45
- return np.allclose(hist.variances(), hist.values())
52
+ return np.allclose(hist.variances(), hist.values(), equal_nan=True)
46
53
 
47
54
 
48
55
  def get_asymmetrical_uncertainties(
49
56
  hist: bh.Histogram,
57
+ uncertainty_type: str = "asymmetrical",
50
58
  ) -> tuple[np.ndarray, np.ndarray]:
51
59
  """
52
60
  Get Poisson asymmetrical uncertainties for a histogram via a frequentist approach based on a confidence-interval computation.
@@ -57,6 +65,8 @@ def get_asymmetrical_uncertainties(
57
65
  ----------
58
66
  hist : bh.Histogram
59
67
  The histogram.
68
+ uncertainty_type : str, optional
69
+ The type of uncertainty to compute for bins with 0 entry. Default is "asymmetrical" (= "asymmetrical_one_sided_zeros"). Use "asymmetrical_double_sided_zeros" to have the double-sided definition. More information in :ref:`documentation-statistics-label`.
60
70
 
61
71
  Returns
62
72
  -------
@@ -72,16 +82,44 @@ def get_asymmetrical_uncertainties(
72
82
 
73
83
  """
74
84
  _check_counting_histogram(hist)
85
+ _check_uncertainty_type(uncertainty_type)
75
86
 
76
87
  if not _is_unweighted(hist):
77
88
  raise ValueError(
78
89
  "Asymmetrical uncertainties can only be computed for an unweighted histogram."
79
90
  )
80
- conf_level = 0.682689492
81
- alpha = 1.0 - conf_level
91
+
92
+ alpha = 1.0 - 0.682689492
93
+ tail_probability = alpha / 2
94
+
82
95
  n = hist.values()
83
- uncertainties_low = n - stats.gamma.ppf(alpha / 2, n, scale=1)
84
- uncertainties_high = stats.gamma.ppf(1 - alpha / 2, n + 1, scale=1) - n
96
+
97
+ lower_bound = np.zeros_like(n, dtype=float)
98
+ upper_bound = np.zeros_like(n, dtype=float)
99
+
100
+ # Two-sided Garwood intervals for n > 0
101
+ lower_bound[n > 0] = stats.gamma.ppf(q=tail_probability, a=n[n > 0], scale=1)
102
+ upper_bound[n > 0] = stats.gamma.ppf(
103
+ q=1 - tail_probability, a=n[n > 0] + 1, scale=1
104
+ )
105
+
106
+ if uncertainty_type == "asymmetrical_double_sided_zeros":
107
+ # Two-sided Garwood intervals for n == 0
108
+ upper_bound[n == 0] = stats.gamma.ppf(q=1 - tail_probability, a=1, scale=1)
109
+ elif uncertainty_type in ["asymmetrical_one_sided_zeros", "asymmetrical"]:
110
+ # One-sided upper limit for n == 0
111
+ upper_bound[n == 0] = stats.gamma.ppf(q=1 - 2 * tail_probability, a=1, scale=1)
112
+ else:
113
+ raise ValueError(
114
+ f"Invalid uncertainty type '{uncertainty_type}' for asymmetrical uncertainties."
115
+ )
116
+
117
+ # Compute asymmetric uncertainties
118
+ uncertainties_low = n - lower_bound
119
+ uncertainties_high = upper_bound - n
120
+
121
+ uncertainties_low = np.nan_to_num(uncertainties_low, nan=0.0)
122
+ uncertainties_high = np.nan_to_num(uncertainties_high, nan=0.0)
85
123
 
86
124
  return uncertainties_low, uncertainties_high
87
125
 
@@ -174,8 +212,10 @@ def get_pull(
174
212
  _check_counting_histogram(h1)
175
213
  _check_counting_histogram(h2)
176
214
 
177
- if h1_uncertainty_type == "asymmetrical":
178
- uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(h1)
215
+ if "asymmetrical" in h1_uncertainty_type:
216
+ uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
217
+ h1, h1_uncertainty_type
218
+ )
179
219
  h1_variances = np.where(
180
220
  h1.values() >= h2.values(),
181
221
  uncertainties_low**2,
@@ -232,8 +272,10 @@ def get_difference(
232
272
 
233
273
  difference_values = h1.values() - h2.values()
234
274
 
235
- if h1_uncertainty_type == "asymmetrical":
236
- uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(h1)
275
+ if "asymmetrical" in h1_uncertainty_type:
276
+ uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
277
+ h1, h1_uncertainty_type
278
+ )
237
279
 
238
280
  difference_uncertainties_low = np.sqrt(uncertainties_low**2 + h2.variances())
239
281
  difference_uncertainties_high = np.sqrt(uncertainties_high**2 + h2.variances())
@@ -390,11 +432,13 @@ def get_ratio(
390
432
 
391
433
  ratio_values = np.where(h2.values() != 0, h1.values() / h2.values(), np.nan)
392
434
 
393
- if h1_uncertainty_type == "asymmetrical":
394
- uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(h1)
435
+ if "asymmetrical" in h1_uncertainty_type:
436
+ uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
437
+ h1, h1_uncertainty_type
438
+ )
395
439
 
396
440
  if ratio_uncertainty_type == "uncorrelated":
397
- if h1_uncertainty_type == "asymmetrical":
441
+ if "asymmetrical" in h1_uncertainty_type:
398
442
  h1_high = h1.copy()
399
443
  h1_high[:] = np.c_[h1_high.values(), uncertainties_high**2]
400
444
  h1_low = h1.copy()
@@ -405,7 +449,7 @@ def get_ratio(
405
449
  ratio_uncertainties_low = np.sqrt(get_ratio_variances(h1, h2))
406
450
  ratio_uncertainties_high = ratio_uncertainties_low
407
451
  elif ratio_uncertainty_type == "split":
408
- if h1_uncertainty_type == "asymmetrical":
452
+ if "asymmetrical" in h1_uncertainty_type:
409
453
  ratio_uncertainties_low = uncertainties_low / h2.values()
410
454
  ratio_uncertainties_high = uncertainties_high / h2.values()
411
455
  else:
@@ -493,7 +537,7 @@ def get_comparison(
493
537
  h1, h2, h1_uncertainty_type
494
538
  )
495
539
  elif comparison == "asymmetry":
496
- if h1_uncertainty_type == "asymmetrical":
540
+ if "asymmetrical" in h1_uncertainty_type:
497
541
  raise ValueError(
498
542
  "Asymmetrical uncertainties are not supported for the asymmetry comparison."
499
543
  )
@@ -501,7 +545,7 @@ def get_comparison(
501
545
  lower_uncertainties = uncertainties
502
546
  upper_uncertainties = uncertainties
503
547
  elif comparison == "efficiency":
504
- if h1_uncertainty_type == "asymmetrical":
548
+ if "asymmetrical" in h1_uncertainty_type:
505
549
  raise ValueError(
506
550
  "Asymmetrical uncertainties are not supported in an efficiency computation."
507
551
  )
@@ -20,7 +20,7 @@ from plothist import (
20
20
  get_variable_from_registry,
21
21
  make_2d_hist,
22
22
  plot_2d_hist,
23
- update_variable_registry_ranges,
23
+ update_variable_registry_binning,
24
24
  )
25
25
 
26
26
  # No need to redo this step if the registry was already created before
@@ -28,7 +28,7 @@ variable_keys = ["variable_0", "variable_1", "variable_2"]
28
28
  unique_id = str(int(time.time() * 1000))[-8:] # unique ID based on current time
29
29
  temporary_registry_path = f"./_temporary_variable_registry_{unique_id}.yaml"
30
30
  create_variable_registry(variable_keys, path=temporary_registry_path)
31
- update_variable_registry_ranges(df, variable_keys, path=temporary_registry_path)
31
+ update_variable_registry_binning(df, variable_keys, path=temporary_registry_path)
32
32
 
33
33
  # Get all the correlation plot between the variables
34
34
  variable_keys_combinations = list(combinations(variable_keys, 2))