plothist 1.3.2__py3-none-any.whl → 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. plothist/__init__.py +66 -74
  2. plothist/_version.py +21 -0
  3. plothist/_version.pyi +2 -0
  4. plothist/comparison.py +115 -106
  5. plothist/examples/1d_hist/1d_comparison_asymmetry.py +37 -0
  6. plothist/examples/1d_hist/1d_comparison_difference.py +40 -0
  7. plothist/examples/1d_hist/1d_comparison_efficiency.py +37 -0
  8. plothist/examples/1d_hist/1d_comparison_only_efficiency.py +33 -0
  9. plothist/examples/1d_hist/1d_comparison_pull.py +37 -0
  10. plothist/examples/1d_hist/1d_comparison_ratio.py +37 -0
  11. plothist/examples/1d_hist/1d_comparison_relative_difference.py +37 -0
  12. plothist/examples/1d_hist/1d_comparison_split_ratio.py +37 -0
  13. plothist/examples/1d_hist/1d_elt1.py +38 -0
  14. plothist/examples/1d_hist/1d_elt1_stacked.py +45 -0
  15. plothist/examples/1d_hist/1d_elt2.py +33 -0
  16. plothist/examples/1d_hist/1d_hist_simple.py +28 -0
  17. plothist/examples/1d_hist/1d_int_category.py +41 -0
  18. plothist/examples/1d_hist/1d_profile.py +33 -0
  19. plothist/examples/1d_hist/1d_side_by_side.py +58 -0
  20. plothist/examples/1d_hist/1d_str_category.py +41 -0
  21. plothist/examples/1d_hist/README.rst +4 -0
  22. plothist/examples/2d_hist/2d_hist_correlations.py +65 -0
  23. plothist/examples/2d_hist/2d_hist_simple.py +28 -0
  24. plothist/examples/2d_hist/2d_hist_simple_discrete_colormap.py +42 -0
  25. plothist/examples/2d_hist/2d_hist_uneven.py +28 -0
  26. plothist/examples/2d_hist/2d_hist_with_projections.py +36 -0
  27. plothist/examples/2d_hist/README.rst +4 -0
  28. plothist/examples/README.rst +7 -0
  29. plothist/examples/advanced/1d_comparison_advanced.py +87 -0
  30. plothist/examples/advanced/1d_side_by_side_with_numbers.py +81 -0
  31. plothist/examples/advanced/README.rst +4 -0
  32. plothist/examples/advanced/asymmetry_comparison_advanced.py +133 -0
  33. plothist/examples/advanced/model_examples_flatten2D.py +86 -0
  34. plothist/examples/func_1d/README.rst +4 -0
  35. plothist/examples/func_1d/fct_1d.py +27 -0
  36. plothist/examples/func_1d/fct_1d_stacked.py +42 -0
  37. plothist/examples/model_ex/README.rst +4 -0
  38. plothist/examples/model_ex/model_all_comparisons.py +103 -0
  39. plothist/examples/model_ex/model_all_comparisons_no_model_unc.py +115 -0
  40. plothist/examples/model_ex/model_examples_pull.py +56 -0
  41. plothist/examples/model_ex/model_examples_pull_no_model_unc.py +59 -0
  42. plothist/examples/model_ex/model_examples_stacked.py +74 -0
  43. plothist/examples/model_ex/model_examples_stacked_unstacked.py +60 -0
  44. plothist/examples/model_ex/model_examples_unstacked.py +57 -0
  45. plothist/examples/model_ex/model_with_stacked_and_unstacked_function_components.py +50 -0
  46. plothist/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py +69 -0
  47. plothist/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py +61 -0
  48. plothist/examples/utility/README.rst +4 -0
  49. plothist/examples/utility/add_text_example.py +39 -0
  50. plothist/examples/utility/color_palette_hists.py +94 -0
  51. plothist/examples/utility/color_palette_squares.py +100 -0
  52. plothist/examples/utility/matplotlib_vs_plothist_style.py +63 -0
  53. plothist/histogramming.py +77 -48
  54. plothist/plothist_style.py +61 -62
  55. plothist/plotters.py +280 -233
  56. plothist/test_helpers.py +43 -0
  57. plothist/variable_registry.py +62 -43
  58. {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/METADATA +20 -12
  59. plothist-1.5.0.dist-info/RECORD +63 -0
  60. {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/licenses/LICENSE +1 -1
  61. plothist/dummy_data.csv +0 -100001
  62. plothist/get_dummy_data.py +0 -17
  63. plothist/scripts/__init__.py +0 -2
  64. plothist/scripts/install_latin_modern_fonts.py +0 -145
  65. plothist/scripts/make_examples.py +0 -210
  66. plothist-1.3.2.dist-info/RECORD +0 -18
  67. plothist-1.3.2.dist-info/entry_points.txt +0 -3
  68. {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/WHEEL +0 -0
  69. {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/licenses/AUTHORS.md +0 -0
plothist/__init__.py CHANGED
@@ -1,115 +1,107 @@
1
+ from __future__ import annotations
2
+
3
+ from ._version import version as __version__
4
+ from .comparison import (
5
+ get_asymmetrical_uncertainties,
6
+ get_comparison,
7
+ get_difference,
8
+ get_pull,
9
+ get_ratio,
10
+ get_ratio_variances,
11
+ )
12
+ from .histogramming import (
13
+ create_axis,
14
+ flatten_2d_hist,
15
+ make_2d_hist,
16
+ make_hist,
17
+ )
18
+ from .plothist_style import (
19
+ add_luminosity,
20
+ add_text,
21
+ cubehelix_palette,
22
+ get_color_palette,
23
+ plot_reordered_legend,
24
+ set_fitting_ylabel_fontsize,
25
+ set_style,
26
+ )
1
27
  from .plotters import (
2
28
  create_comparison_figure,
3
- plot_hist,
4
29
  plot_2d_hist,
5
30
  plot_2d_hist_with_projections,
31
+ plot_comparison,
32
+ plot_data_model_comparison,
6
33
  plot_error_hist,
34
+ plot_function,
35
+ plot_hist,
7
36
  plot_hist_uncertainties,
37
+ plot_model,
8
38
  plot_two_hist_comparison,
9
- plot_comparison,
10
39
  savefig,
11
- plot_data_model_comparison,
12
- plot_model,
13
- plot_function,
14
40
  )
15
-
16
- from .histogramming import (
17
- create_axis,
18
- make_hist,
19
- make_2d_hist,
20
- flatten_2d_hist,
21
- )
22
-
23
41
  from .variable_registry import (
24
42
  create_variable_registry,
25
43
  get_variable_from_registry,
26
- update_variable_registry,
27
44
  remove_variable_registry_parameters,
45
+ update_variable_registry,
28
46
  update_variable_registry_ranges,
29
47
  )
30
48
 
31
- from .comparison import (
32
- get_asymmetrical_uncertainties,
33
- get_comparison,
34
- get_pull,
35
- get_difference,
36
- get_ratio,
37
- get_ratio_variances,
38
- )
39
-
40
- from .plothist_style import (
41
- set_style,
42
- cubehelix_palette,
43
- get_color_palette,
44
- set_fitting_ylabel_fontsize,
45
- add_text,
46
- add_luminosity,
47
- plot_reordered_legend,
48
- )
49
-
50
- from .get_dummy_data import get_dummy_data
51
-
52
49
  __all__ = [
53
50
  "__version__",
51
+ "add_luminosity",
52
+ "add_text",
53
+ "create_axis",
54
+ "create_comparison_figure",
54
55
  "create_variable_registry",
56
+ "cubehelix_palette",
57
+ "flatten_2d_hist",
58
+ "get_asymmetrical_uncertainties",
59
+ "get_color_palette",
60
+ "get_comparison",
61
+ "get_difference",
62
+ "get_pull",
63
+ "get_ratio",
64
+ "get_ratio_variances",
55
65
  "get_variable_from_registry",
56
- "update_variable_registry",
57
- "remove_variable_registry_parameters",
58
- "update_variable_registry_ranges",
59
- "create_comparison_figure",
60
- "create_axis",
61
- "make_hist",
62
66
  "make_2d_hist",
63
- "plot_hist",
67
+ "make_hist",
64
68
  "plot_2d_hist",
65
69
  "plot_2d_hist_with_projections",
70
+ "plot_comparison",
71
+ "plot_data_model_comparison",
66
72
  "plot_error_hist",
73
+ "plot_function",
74
+ "plot_hist",
67
75
  "plot_hist_uncertainties",
76
+ "plot_model",
77
+ "plot_reordered_legend",
68
78
  "plot_two_hist_comparison",
69
- "plot_comparison",
79
+ "remove_variable_registry_parameters",
70
80
  "savefig",
71
- "plot_data_model_comparison",
72
- "plot_model",
73
- "plot_function",
74
- "add_luminosity",
75
- "get_asymmetrical_uncertainties",
76
- "set_style",
77
- "cubehelix_palette",
78
- "get_color_palette",
79
81
  "set_fitting_ylabel_fontsize",
80
- "add_text",
81
- "get_asymmetrical_uncertainties",
82
- "get_comparison",
83
- "get_pull",
84
- "get_difference",
85
- "get_ratio",
86
- "get_ratio_variances",
87
- "flatten_2d_hist",
88
- "plot_reordered_legend",
89
- "get_dummy_data",
82
+ "set_style",
83
+ "update_variable_registry",
84
+ "update_variable_registry_ranges",
90
85
  ]
91
86
 
92
87
 
93
88
  # Get style file and use it
94
- import matplotlib.pyplot as plt
95
89
  from importlib.resources import files
96
90
 
91
+ import matplotlib.pyplot as plt
92
+
97
93
  style_file = files("plothist").joinpath("default_style.mplstyle")
98
94
  plt.style.use(style_file)
99
95
 
100
- # Check the fonts
101
- from matplotlib.font_manager import findfont
102
- import warnings
96
+ # Install fonts
97
+ from importlib import resources
98
+
99
+ import matplotlib.font_manager as fm
103
100
 
104
- for font_type in ["Math", "Sans", "Roman"]:
105
- try:
106
- findfont(f"Latin Modern {font_type}", fallback_to_default=False)
107
- except:
108
- warnings.warn(
109
- "The recommended fonts to use plothist were not found. You can install them by typing 'install_latin_modern_fonts' in your terminal. If it still does not work, please check the documentation at https://plothist.readthedocs.io/en/latest/usage/font_installation.html",
110
- stacklevel=3,
111
- )
112
- break
101
+ with resources.as_file(resources.files("plothist_utils") / "fonts") as font_path:
102
+ font_files = fm.findSystemFonts(fontpaths=[str(font_path)])
103
+ for font in font_files:
104
+ fm.fontManager.addfont(font)
113
105
 
114
106
  # Check version of boost_histogram
115
107
  import boost_histogram as bh
plothist/_version.py ADDED
@@ -0,0 +1,21 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
6
+ TYPE_CHECKING = False
7
+ if TYPE_CHECKING:
8
+ from typing import Tuple
9
+ from typing import Union
10
+
11
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
12
+ else:
13
+ VERSION_TUPLE = object
14
+
15
+ version: str
16
+ __version__: str
17
+ __version_tuple__: VERSION_TUPLE
18
+ version_tuple: VERSION_TUPLE
19
+
20
+ __version__ = version = '1.5.0'
21
+ __version_tuple__ = version_tuple = (1, 5, 0)
plothist/_version.pyi ADDED
@@ -0,0 +1,2 @@
1
+ version: str
2
+ version_tuple: tuple[int, int, int] | tuple[int, int, int, str, str]
plothist/comparison.py CHANGED
@@ -1,9 +1,13 @@
1
+ from __future__ import annotations
2
+
3
+ import boost_histogram as bh
1
4
  import numpy as np
2
- import scipy.stats as stats
5
+ from scipy import stats
6
+
3
7
  from plothist.histogramming import _check_counting_histogram
4
8
 
5
9
 
6
- def _check_uncertainty_type(uncertainty_type):
10
+ def _check_uncertainty_type(uncertainty_type: str) -> None:
7
11
  """
8
12
  Check that the uncertainty type is valid.
9
13
 
@@ -24,13 +28,13 @@ def _check_uncertainty_type(uncertainty_type):
24
28
  )
25
29
 
26
30
 
27
- def _is_unweighted(hist):
31
+ def _is_unweighted(hist: bh.Histogram) -> bool:
28
32
  """
29
33
  Check whether a histogram is unweighted.
30
34
 
31
35
  Parameters
32
36
  ----------
33
- hist : boost_histogram.Histogram
37
+ hist : bh.Histogram
34
38
  The histogram to check.
35
39
 
36
40
  Returns
@@ -41,7 +45,9 @@ def _is_unweighted(hist):
41
45
  return np.allclose(hist.variances(), hist.values())
42
46
 
43
47
 
44
- def get_asymmetrical_uncertainties(hist):
48
+ def get_asymmetrical_uncertainties(
49
+ hist: bh.Histogram,
50
+ ) -> tuple[np.ndarray, np.ndarray]:
45
51
  """
46
52
  Get Poisson asymmetrical uncertainties for a histogram via a frequentist approach based on a confidence-interval computation.
47
53
  Asymmetrical uncertainties can only be computed for an unweighted histogram, because the bin contents of a weighted histogram do not follow a Poisson distribution.
@@ -49,14 +55,14 @@ def get_asymmetrical_uncertainties(hist):
49
55
 
50
56
  Parameters
51
57
  ----------
52
- hist : boost_histogram.Histogram
58
+ hist : bh.Histogram
53
59
  The histogram.
54
60
 
55
61
  Returns
56
62
  -------
57
- uncertainties_low : numpy.ndarray
63
+ uncertainties_low : np.ndarray
58
64
  The lower uncertainties.
59
- uncertainties_high : numpy.ndarray
65
+ uncertainties_high : np.ndarray
60
66
  The upper uncertainties.
61
67
 
62
68
  Raise
@@ -80,13 +86,13 @@ def get_asymmetrical_uncertainties(hist):
80
86
  return uncertainties_low, uncertainties_high
81
87
 
82
88
 
83
- def _check_binning_consistency(hist_list):
89
+ def _check_binning_consistency(hist_list: list[bh.Histogram]) -> None:
84
90
  """
85
91
  Check that all the histograms in the provided list share the same definition of their bins.
86
92
 
87
93
  Parameters
88
94
  ----------
89
- hist_list : list of boost_histogram.Histogram
95
+ hist_list : list[bh.Histogram]
90
96
  The list of histograms to check.
91
97
 
92
98
  Raise
@@ -103,15 +109,15 @@ def _check_binning_consistency(hist_list):
103
109
  raise ValueError("The bins of the histograms must be equal.")
104
110
 
105
111
 
106
- def get_ratio_variances(h1, h2):
112
+ def get_ratio_variances(h1: bh.Histogram, h2: bh.Histogram) -> np.ndarray:
107
113
  """
108
114
  Calculate the variances of the ratio of two uncorrelated histograms (h1/h2).
109
115
 
110
116
  Parameters
111
117
  ----------
112
- h1 : boost_histogram.Histogram
118
+ h1 : bh.Histogram
113
119
  The first histogram.
114
- h2 : boost_histogram.Histogram
120
+ h2 : bh.Histogram
115
121
  The second histogram.
116
122
 
117
123
  Returns
@@ -128,38 +134,39 @@ def get_ratio_variances(h1, h2):
128
134
  _check_counting_histogram(h1)
129
135
  _check_counting_histogram(h2)
130
136
 
131
- np.seterr(divide="ignore", invalid="ignore")
132
- ratio_variances = np.where(
133
- h2.values() != 0,
134
- h1.variances() / h2.values() ** 2
135
- + h2.variances() * h1.values() ** 2 / h2.values() ** 4,
136
- np.nan,
137
- )
138
- np.seterr(divide="warn", invalid="warn")
139
-
140
- return ratio_variances
137
+ with np.errstate(divide="ignore", invalid="ignore"):
138
+ return np.where(
139
+ h2.values() != 0,
140
+ h1.variances() / h2.values() ** 2
141
+ + h2.variances() * h1.values() ** 2 / h2.values() ** 4,
142
+ np.nan,
143
+ )
141
144
 
142
145
 
143
- def get_pull(h1, h2, h1_uncertainty_type="symmetrical"):
146
+ def get_pull(
147
+ h1: bh.Histogram,
148
+ h2: bh.Histogram,
149
+ h1_uncertainty_type: str = "symmetrical",
150
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
144
151
  """
145
152
  Compute the pull between two histograms.
146
153
 
147
154
  Parameters
148
155
  ----------
149
- h1 : boost_histogram.Histogram
156
+ h1 : bh.Histogram
150
157
  The first histogram.
151
- h2 : boost_histogram.Histogram
158
+ h2 : bh.Histogram
152
159
  The second histogram.
153
160
  h1_uncertainty_type : str, optional
154
161
  What kind of bin uncertainty to use for h1: "symmetrical" for the Poisson standard deviation derived from the variance stored in the histogram object, "asymmetrical" for asymmetrical uncertainties based on a Poisson confidence interval. Default is "symmetrical".
155
162
 
156
163
  Returns
157
164
  -------
158
- pull_values : numpy.ndarray
165
+ pull_values : np.ndarray
159
166
  The pull values.
160
- pull_uncertainties_low : numpy.ndarray
167
+ pull_uncertainties_low : np.ndarray
161
168
  The lower uncertainties on the pull. Always ones.
162
- pull_uncertainties_high : numpy.ndarray
169
+ pull_uncertainties_high : np.ndarray
163
170
  The upper uncertainties on the pull. Always ones.
164
171
  """
165
172
  _check_uncertainty_type(h1_uncertainty_type)
@@ -192,26 +199,30 @@ def get_pull(h1, h2, h1_uncertainty_type="symmetrical"):
192
199
  )
193
200
 
194
201
 
195
- def get_difference(h1, h2, h1_uncertainty_type="symmetrical"):
202
+ def get_difference(
203
+ h1: bh.Histogram,
204
+ h2: bh.Histogram,
205
+ h1_uncertainty_type: str = "symmetrical",
206
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
196
207
  """
197
208
  Compute the difference between two histograms.
198
209
 
199
210
  Parameters
200
211
  ----------
201
- h1 : boost_histogram.Histogram
212
+ h1 : bh.Histogram
202
213
  The first histogram.
203
- h2 : boost_histogram.Histogram
214
+ h2 : bh.Histogram
204
215
  The second histogram.
205
216
  h1_uncertainty_type : str, optional
206
217
  What kind of bin uncertainty to use for h1: "symmetrical" for the Poisson standard deviation derived from the variance stored in the histogram object, "asymmetrical" for asymmetrical uncertainties based on a Poisson confidence interval. Default is "symmetrical".
207
218
 
208
219
  Returns
209
220
  -------
210
- difference_values : numpy.ndarray
221
+ difference_values : np.ndarray
211
222
  The difference values.
212
- difference_uncertainties_low : numpy.ndarray
223
+ difference_uncertainties_low : np.ndarray
213
224
  The lower uncertainties on the difference.
214
- difference_uncertainties_high : numpy.ndarray
225
+ difference_uncertainties_high : np.ndarray
215
226
  The upper uncertainties on the difference.
216
227
  """
217
228
  _check_uncertainty_type(h1_uncertainty_type)
@@ -237,7 +248,7 @@ def get_difference(h1, h2, h1_uncertainty_type="symmetrical"):
237
248
  )
238
249
 
239
250
 
240
- def get_efficency(h1, h2):
251
+ def get_efficiency(h1: bh.Histogram, h2: bh.Histogram) -> tuple[np.ndarray, np.ndarray]:
241
252
  """
242
253
  Calculate the ratio of two correlated histograms (h1/h2), in which the entries of h1 are a subsample of the entries of h2.
243
254
  The variances are calculated according to the formula given in :ref:`documentation-statistics-label`.
@@ -250,16 +261,16 @@ def get_efficency(h1, h2):
250
261
 
251
262
  Parameters
252
263
  ----------
253
- h1 : boost_histogram.Histogram
264
+ h1 : bh.Histogram
254
265
  The first histogram.
255
- h2 : boost_histogram.Histogram
266
+ h2 : bh.Histogram
256
267
  The second histogram.
257
268
 
258
269
  Returns
259
270
  -------
260
- efficiency_values : numpy.ndarray
271
+ efficiency_values : np.ndarray
261
272
  The efficiency values.
262
- efficiency_uncertainties : numpy.ndarray
273
+ efficiency_uncertainties : np.ndarray
263
274
  The uncertainties on the efficiency values.
264
275
 
265
276
  Raises
@@ -300,23 +311,23 @@ def get_efficency(h1, h2):
300
311
  return efficiency_values, np.sqrt(efficiency_variances)
301
312
 
302
313
 
303
- def get_asymmetry(h1, h2):
314
+ def get_asymmetry(h1: bh.Histogram, h2: bh.Histogram) -> tuple[np.ndarray, np.ndarray]:
304
315
  """
305
316
  Get the asymmetry between two histograms h1 and h2, defined as (h1 - h2) / (h1 + h2).
306
317
  Only symmetrical uncertainties are supported.
307
318
 
308
319
  Parameters
309
320
  ----------
310
- h1 : boost_histogram.Histogram
321
+ h1 : bh.Histogram
311
322
  The first histogram.
312
- h2 : boost_histogram.Histogram
323
+ h2 : bh.Histogram
313
324
  The second histogram.
314
325
 
315
326
  Returns
316
327
  -------
317
- asymmetry_values : numpy.ndarray
328
+ asymmetry_values : np.ndarray
318
329
  The asymmetry values.
319
- asymmetry_uncertainties : numpy.ndarray
330
+ asymmetry_uncertainties : np.ndarray
320
331
  The uncertainties on the asymmetry.
321
332
  """
322
333
  _check_binning_consistency([h1, h2])
@@ -336,19 +347,19 @@ def get_asymmetry(h1, h2):
336
347
 
337
348
 
338
349
  def get_ratio(
339
- h1,
340
- h2,
341
- h1_uncertainty_type="symmetrical",
342
- ratio_uncertainty_type="uncorrelated",
343
- ):
350
+ h1: bh.Histogram,
351
+ h2: bh.Histogram,
352
+ h1_uncertainty_type: str = "symmetrical",
353
+ ratio_uncertainty_type: str = "uncorrelated",
354
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
344
355
  """
345
356
  Compute the ratio h1/h2 between two uncorrelated histograms h1 and h2.
346
357
 
347
358
  Parameters
348
359
  ----------
349
- h1 : boost_histogram.Histogram
360
+ h1 : bh.Histogram
350
361
  The numerator histogram.
351
- h2 : boost_histogram.Histogram
362
+ h2 : bh.Histogram
352
363
  The denominator histogram.
353
364
  h1_uncertainty_type : str, optional
354
365
  What kind of bin uncertainty to use for h1: "symmetrical" for the Poisson standard deviation derived from the variance stored in the histogram object, "asymmetrical" for asymmetrical uncertainties based on a Poisson confidence interval. Default is "symmetrical".
@@ -360,11 +371,11 @@ def get_ratio(
360
371
 
361
372
  Returns
362
373
  -------
363
- ratio_values : numpy.ndarray
374
+ ratio_values : np.ndarray
364
375
  The ratio values.
365
- ratio_uncertainties_low : numpy.ndarray
376
+ ratio_uncertainties_low : np.ndarray
366
377
  The lower uncertainties on the ratio.
367
- ratio_uncertainties_high : numpy.ndarray
378
+ ratio_uncertainties_high : np.ndarray
368
379
  The upper uncertainties on the ratio.
369
380
 
370
381
  Raises
@@ -416,19 +427,19 @@ def get_ratio(
416
427
 
417
428
 
418
429
  def get_comparison(
419
- h1,
420
- h2,
421
- comparison,
422
- h1_uncertainty_type="symmetrical",
423
- ):
430
+ h1: bh.Histogram,
431
+ h2: bh.Histogram,
432
+ comparison: str,
433
+ h1_uncertainty_type: str = "symmetrical",
434
+ ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
424
435
  """
425
436
  Compute the comparison between two histograms.
426
437
 
427
438
  Parameters
428
439
  ----------
429
- h1 : boost_histogram.Histogram
440
+ h1 : bh.Histogram
430
441
  The first histogram for comparison.
431
- h2 : boost_histogram.Histogram
442
+ h2 : bh.Histogram
432
443
  The second histogram for comparison.
433
444
  comparison : str
434
445
  The type of comparison ("ratio", "split_ratio", "pull", "difference", "relative_difference", "efficiency", or "asymmetry").
@@ -440,11 +451,11 @@ def get_comparison(
440
451
 
441
452
  Returns
442
453
  -------
443
- values : numpy.ndarray
454
+ values : np.ndarray
444
455
  The comparison values.
445
- lower_uncertainties : numpy.ndarray
456
+ lower_uncertainties : np.ndarray
446
457
  The lower uncertainties on the comparison values.
447
- upper_uncertainties : numpy.ndarray
458
+ upper_uncertainties : np.ndarray
448
459
  The upper uncertainties on the comparison values.
449
460
 
450
461
  Raises
@@ -459,49 +470,47 @@ def get_comparison(
459
470
  _check_counting_histogram(h1)
460
471
  _check_counting_histogram(h2)
461
472
 
462
- np.seterr(divide="ignore", invalid="ignore")
463
-
464
- if comparison == "ratio":
465
- values, lower_uncertainties, upper_uncertainties = get_ratio(
466
- h1, h2, h1_uncertainty_type, "uncorrelated"
467
- )
468
- elif comparison == "split_ratio":
469
- values, lower_uncertainties, upper_uncertainties = get_ratio(
470
- h1, h2, h1_uncertainty_type, "split"
471
- )
472
- elif comparison == "relative_difference":
473
- values, lower_uncertainties, upper_uncertainties = get_ratio(
474
- h1, h2, h1_uncertainty_type, "uncorrelated"
475
- )
476
- values -= 1 # relative difference is ratio-1
477
- elif comparison == "pull":
478
- values, lower_uncertainties, upper_uncertainties = get_pull(
479
- h1, h2, h1_uncertainty_type
480
- )
481
- elif comparison == "difference":
482
- values, lower_uncertainties, upper_uncertainties = get_difference(
483
- h1, h2, h1_uncertainty_type
484
- )
485
- elif comparison == "asymmetry":
486
- if h1_uncertainty_type == "asymmetrical":
487
- raise ValueError(
488
- "Asymmetrical uncertainties are not supported for the asymmetry comparison."
473
+ with np.errstate(divide="ignore", invalid="ignore"):
474
+ if comparison == "ratio":
475
+ values, lower_uncertainties, upper_uncertainties = get_ratio(
476
+ h1, h2, h1_uncertainty_type, "uncorrelated"
489
477
  )
490
- values, uncertainties = get_asymmetry(h1, h2)
491
- lower_uncertainties = uncertainties
492
- upper_uncertainties = uncertainties
493
- elif comparison == "efficiency":
494
- if h1_uncertainty_type == "asymmetrical":
478
+ elif comparison == "split_ratio":
479
+ values, lower_uncertainties, upper_uncertainties = get_ratio(
480
+ h1, h2, h1_uncertainty_type, "split"
481
+ )
482
+ elif comparison == "relative_difference":
483
+ values, lower_uncertainties, upper_uncertainties = get_ratio(
484
+ h1, h2, h1_uncertainty_type, "uncorrelated"
485
+ )
486
+ values -= 1 # relative difference is ratio-1
487
+ elif comparison == "pull":
488
+ values, lower_uncertainties, upper_uncertainties = get_pull(
489
+ h1, h2, h1_uncertainty_type
490
+ )
491
+ elif comparison == "difference":
492
+ values, lower_uncertainties, upper_uncertainties = get_difference(
493
+ h1, h2, h1_uncertainty_type
494
+ )
495
+ elif comparison == "asymmetry":
496
+ if h1_uncertainty_type == "asymmetrical":
497
+ raise ValueError(
498
+ "Asymmetrical uncertainties are not supported for the asymmetry comparison."
499
+ )
500
+ values, uncertainties = get_asymmetry(h1, h2)
501
+ lower_uncertainties = uncertainties
502
+ upper_uncertainties = uncertainties
503
+ elif comparison == "efficiency":
504
+ if h1_uncertainty_type == "asymmetrical":
505
+ raise ValueError(
506
+ "Asymmetrical uncertainties are not supported in an efficiency computation."
507
+ )
508
+ values, uncertainties = get_efficiency(h1, h2)
509
+ lower_uncertainties = uncertainties
510
+ upper_uncertainties = uncertainties
511
+ else:
495
512
  raise ValueError(
496
- "Asymmetrical uncertainties are not supported in an efficiency computation."
513
+ f"{comparison} not available as a comparison ('ratio', 'split_ratio', 'pull', 'difference', 'relative_difference', 'asymmetry' or 'efficiency')."
497
514
  )
498
- values, uncertainties = get_efficency(h1, h2)
499
- lower_uncertainties = uncertainties
500
- upper_uncertainties = uncertainties
501
- else:
502
- raise ValueError(
503
- f"{comparison} not available as a comparison ('ratio', 'split_ratio', 'pull', 'difference', 'relative_difference', 'asymmetry' or 'efficiency')."
504
- )
505
- np.seterr(divide="warn", invalid="warn")
506
515
 
507
516
  return values, lower_uncertainties, upper_uncertainties
@@ -0,0 +1,37 @@
1
+ """
2
+ Asymmetry
3
+ =========
4
+
5
+ Compare two 1D histograms using the asymmetry comparison [(h1-h2)/(h1+h2)].
6
+ """
7
+
8
+ from plothist_utils import get_dummy_data
9
+
10
+ df = get_dummy_data()
11
+
12
+ name = "variable_1"
13
+
14
+ x1 = df[name][df["category"] == 2]
15
+ x2 = df[name][df["category"] == 3]
16
+
17
+ x_range = (min(*x1, *x2), max(*x1, *x2))
18
+
19
+ from plothist import make_hist
20
+
21
+ h1 = make_hist(x1, bins=50, range=x_range)
22
+ h2 = make_hist(x2, bins=50, range=x_range)
23
+
24
+ ###
25
+ from plothist import plot_two_hist_comparison
26
+
27
+ fig, ax_main, ax_comparison = plot_two_hist_comparison(
28
+ h1,
29
+ h2,
30
+ xlabel=name,
31
+ ylabel="Entries",
32
+ h1_label=r"$\mathbfit{h}_1$",
33
+ h2_label=r"$\mathbfit{h}_2$",
34
+ comparison="asymmetry", # <--
35
+ )
36
+
37
+ fig.savefig("1d_comparison_asymmetry.svg", bbox_inches="tight")