plothist 1.4.0__py3-none-any.whl → 1.6.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 (66) hide show
  1. plothist/__init__.py +5 -5
  2. plothist/_version.py +2 -2
  3. plothist/comparison.py +170 -120
  4. plothist/examples/1d_hist/1d_comparison_asymmetry.py +37 -0
  5. plothist/examples/1d_hist/1d_comparison_difference.py +40 -0
  6. plothist/examples/1d_hist/1d_comparison_efficiency.py +37 -0
  7. plothist/examples/1d_hist/1d_comparison_only_efficiency.py +33 -0
  8. plothist/examples/1d_hist/1d_comparison_pull.py +37 -0
  9. plothist/examples/1d_hist/1d_comparison_ratio.py +37 -0
  10. plothist/examples/1d_hist/1d_comparison_relative_difference.py +37 -0
  11. plothist/examples/1d_hist/1d_comparison_split_ratio.py +37 -0
  12. plothist/examples/1d_hist/1d_elt1.py +38 -0
  13. plothist/examples/1d_hist/1d_elt1_stacked.py +45 -0
  14. plothist/examples/1d_hist/1d_elt2.py +33 -0
  15. plothist/examples/1d_hist/1d_hist_simple.py +28 -0
  16. plothist/examples/1d_hist/1d_int_category.py +41 -0
  17. plothist/examples/1d_hist/1d_profile.py +33 -0
  18. plothist/examples/1d_hist/1d_side_by_side.py +58 -0
  19. plothist/examples/1d_hist/1d_str_category.py +41 -0
  20. plothist/examples/1d_hist/README.rst +4 -0
  21. plothist/examples/2d_hist/2d_hist_correlations.py +65 -0
  22. plothist/examples/2d_hist/2d_hist_simple.py +28 -0
  23. plothist/examples/2d_hist/2d_hist_simple_discrete_colormap.py +42 -0
  24. plothist/examples/2d_hist/2d_hist_uneven.py +28 -0
  25. plothist/examples/2d_hist/2d_hist_with_projections.py +36 -0
  26. plothist/examples/2d_hist/README.rst +4 -0
  27. plothist/examples/README.rst +7 -0
  28. plothist/examples/advanced/1d_comparison_advanced.py +87 -0
  29. plothist/examples/advanced/1d_side_by_side_with_numbers.py +81 -0
  30. plothist/examples/advanced/README.rst +4 -0
  31. plothist/examples/advanced/asymmetry_comparison_advanced.py +133 -0
  32. plothist/examples/advanced/model_examples_flatten2D.py +86 -0
  33. plothist/examples/func_1d/README.rst +4 -0
  34. plothist/examples/func_1d/fct_1d.py +27 -0
  35. plothist/examples/func_1d/fct_1d_stacked.py +42 -0
  36. plothist/examples/model_ex/README.rst +4 -0
  37. plothist/examples/model_ex/model_all_comparisons.py +103 -0
  38. plothist/examples/model_ex/model_all_comparisons_no_model_unc.py +115 -0
  39. plothist/examples/model_ex/model_examples_pull.py +56 -0
  40. plothist/examples/model_ex/model_examples_pull_no_model_unc.py +59 -0
  41. plothist/examples/model_ex/model_examples_stacked.py +74 -0
  42. plothist/examples/model_ex/model_examples_stacked_unstacked.py +60 -0
  43. plothist/examples/model_ex/model_examples_unstacked.py +57 -0
  44. plothist/examples/model_ex/model_with_stacked_and_unstacked_function_components.py +50 -0
  45. plothist/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py +69 -0
  46. plothist/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py +61 -0
  47. plothist/examples/utility/README.rst +4 -0
  48. plothist/examples/utility/add_text_example.py +39 -0
  49. plothist/examples/utility/color_palette_hists.py +94 -0
  50. plothist/examples/utility/color_palette_squares.py +100 -0
  51. plothist/examples/utility/matplotlib_vs_plothist_style.py +63 -0
  52. plothist/examples/utility/uncertainty_types.py +120 -0
  53. plothist/histogramming.py +60 -39
  54. plothist/plothist_style.py +56 -59
  55. plothist/plotters.py +210 -195
  56. plothist/test_helpers.py +43 -0
  57. plothist/variable_registry.py +46 -30
  58. {plothist-1.4.0.dist-info → plothist-1.6.0.dist-info}/METADATA +1 -1
  59. plothist-1.6.0.dist-info/RECORD +64 -0
  60. plothist/scripts/__init__.py +0 -3
  61. plothist/scripts/make_examples.py +0 -209
  62. plothist-1.4.0.dist-info/RECORD +0 -17
  63. plothist-1.4.0.dist-info/entry_points.txt +0 -2
  64. {plothist-1.4.0.dist-info → plothist-1.6.0.dist-info}/WHEEL +0 -0
  65. {plothist-1.4.0.dist-info → plothist-1.6.0.dist-info}/licenses/AUTHORS.md +0 -0
  66. {plothist-1.4.0.dist-info → plothist-1.6.0.dist-info}/licenses/LICENSE +0 -0
plothist/plotters.py CHANGED
@@ -5,6 +5,7 @@ Collection of functions to plot histograms
5
5
  from __future__ import annotations
6
6
 
7
7
  import re
8
+ from typing import Callable
8
9
 
9
10
  import boost_histogram as bh
10
11
  import matplotlib.pyplot as plt
@@ -22,34 +23,32 @@ from plothist.plothist_style import set_fitting_ylabel_fontsize
22
23
 
23
24
 
24
25
  def create_comparison_figure(
25
- figsize=(6, 5),
26
- nrows=2,
27
- gridspec_kw=None,
28
- hspace=0.15,
29
- ):
26
+ figsize: tuple[float, float] = (6, 5),
27
+ nrows: int = 2,
28
+ gridspec_kw: dict | None = None,
29
+ hspace: float = 0.15,
30
+ ) -> tuple[plt.Figure, np.ndarray]:
30
31
  """
31
32
  Create a figure with subplots for comparison.
32
33
 
33
34
  Parameters
34
35
  ----------
35
- figsize : tuple, optional
36
+ figsize : tuple[float, float], optional
36
37
  Figure size in inches. Default is (6, 5).
37
38
  nrows : int, optional
38
39
  Number of rows in the subplot grid. Default is 2.
39
- gridspec_kw : dict, optional
40
+ gridspec_kw : dict | None, optional
40
41
  Additional keyword arguments for the GridSpec. Default is None.
41
42
  If None is provided, this is set to {"height_ratios": [4, 1]}.
42
43
  hspace : float, optional
43
44
  Height spacing between subplots. Default is 0.15.
44
45
 
45
-
46
46
  Returns
47
47
  -------
48
48
  fig : matplotlib.figure.Figure
49
49
  The created figure.
50
- axes : ndarray
50
+ axes : np.ndarray
51
51
  Array of Axes objects representing the subplots.
52
-
53
52
  """
54
53
  if gridspec_kw is None:
55
54
  gridspec_kw = {"height_ratios": [4, 1]}
@@ -66,13 +65,13 @@ def create_comparison_figure(
66
65
  return fig, axes
67
66
 
68
67
 
69
- def plot_hist(hist, ax, **kwargs):
68
+ def plot_hist(hist: bh.Histogram | list[bh.Histogram], ax: plt.Axes, **kwargs) -> None:
70
69
  """
71
70
  Plot a histogram or a list of histograms from boost_histogram.
72
71
 
73
72
  Parameters
74
73
  ----------
75
- hist : boost_histogram.Histogram or list of boost_histogram.Histogram
74
+ hist : bh.Histogram | list[bh.Histogram]
76
75
  The histogram(s) to plot.
77
76
  ax : matplotlib.axes.Axes
78
77
  The Axes instance for plotting.
@@ -101,33 +100,33 @@ def plot_hist(hist, ax, **kwargs):
101
100
 
102
101
 
103
102
  def plot_2d_hist(
104
- hist,
105
- fig=None,
106
- ax=None,
107
- ax_colorbar=None,
108
- pcolormesh_kwargs=None,
109
- colorbar_kwargs=None,
110
- square_ax=True,
111
- ):
103
+ hist: bh.Histogram,
104
+ fig: plt.Figure | None = None,
105
+ ax: plt.Axes | None = None,
106
+ ax_colorbar: plt.Axes | None = None,
107
+ pcolormesh_kwargs: dict | None = None,
108
+ colorbar_kwargs: dict | None = None,
109
+ square_ax: bool = True,
110
+ ) -> tuple[plt.Figure, plt.Axes, plt.Axes]:
112
111
  """
113
112
  Plot a 2D histogram using a pcolormesh plot and add a colorbar.
114
113
 
115
114
  Parameters
116
115
  ----------
117
- hist : boost_histogram.Histogram
116
+ hist : bh.Histogram
118
117
  The 2D histogram to plot.
119
- fig : matplotlib.figure.Figure, optional
120
- The Figure instance for plotting. If fig, ax and ax_colorbar are None, a new figure will be created. Default is None.
121
- ax : matplotlib.axes.Axes, optional
122
- The Axes instance for plotting. If fig, ax and ax_colorbar are None, a new figure will be created. Default is None.
123
- ax_colorbar : matplotlib.axes.Axes
124
- The Axes instance for the colorbar. If fig, ax and ax_colorbar are None, a new figure will be created. Default is None.
125
- pcolormesh_kwargs : dict, optional
118
+ fig : matplotlib.figure.Figure | None, optional
119
+ The Figure instance for plotting. If fig, ax and ax_colorbar are all None, a new figure will be created. Default is None.
120
+ ax : matplotlib.axes.Axes | None, optional
121
+ The Axes instance for plotting. If fig, ax and ax_colorbar are all None, a new figure will be created. Default is None.
122
+ ax_colorbar : matplotlib.axes.Axes | None, optional
123
+ The Axes instance for the colorbar. If fig, ax and ax_colorbar are all None, a new figure will be created. Default is None.
124
+ pcolormesh_kwargs : dict | None, optional
126
125
  Additional keyword arguments forwarded to ax.pcolormesh(). Default is None.
127
- colorbar_kwargs : dict, optional
126
+ colorbar_kwargs : dict | None, optional
128
127
  Additional keyword arguments forwarded to ax.get_figure().colorbar(). Default is None.
129
128
  square_ax : bool, optional
130
- Whether to make the main ax square (default is True).
129
+ Whether to make the main ax square. Default is True.
131
130
  """
132
131
  if colorbar_kwargs is None:
133
132
  colorbar_kwargs = {}
@@ -156,7 +155,7 @@ def plot_2d_hist(
156
155
  return fig, ax, ax_colorbar
157
156
 
158
157
 
159
- def _invert_collection_order(ax, n=0):
158
+ def _invert_collection_order(ax: plt.Axes, n: int = 0) -> None:
160
159
  """
161
160
  Invert the order of the collection objects in an Axes instance.
162
161
 
@@ -166,7 +165,6 @@ def _invert_collection_order(ax, n=0):
166
165
  The Axes instance for plotting.
167
166
  n : int, optional
168
167
  The number of collections to keep in the original order. Default is 0.
169
-
170
168
  """
171
169
  # Retrieve the list of collection objects
172
170
  collections = list(ax.collections)
@@ -183,17 +181,23 @@ def _invert_collection_order(ax, n=0):
183
181
  ax.add_collection(collection)
184
182
 
185
183
 
186
- def plot_function(func, range, ax, stacked=False, npoints=1000, **kwargs):
184
+ def plot_function(
185
+ func: Callable[[np.ndarray], np.ndarray] | list[Callable[[np.ndarray], np.ndarray]],
186
+ range: tuple[float, float],
187
+ ax: plt.Axes,
188
+ stacked: bool = False,
189
+ npoints: int = 1000,
190
+ **kwargs,
191
+ ) -> None:
187
192
  """
188
193
  Plot a 1D function on a given range.
189
194
 
190
195
  Parameters
191
196
  ----------
192
- func : function or list of functions
193
- The 1D function or list of functions to plot.
194
- The function(s) should support vectorization (i.e. accept a numpy array as input).
195
- range : tuple
196
- The range of the function(s). The function(s) will be plotted on the interval [range[0], range[1]].
197
+ func : Callable[[np.ndarray], np.ndarray] | list[Callable[[np.ndarray], np.ndarray]]
198
+ The 1D function or list of functions to plot. Should support vectorization.
199
+ range : tuple[float, float]
200
+ The range of the function(s). Will be plotted on the interval [range[0], range[1]].
197
201
  ax : matplotlib.axes.Axes
198
202
  The Axes instance for plotting.
199
203
  stacked : bool, optional
@@ -231,43 +235,44 @@ def plot_function(func, range, ax, stacked=False, npoints=1000, **kwargs):
231
235
 
232
236
 
233
237
  def plot_2d_hist_with_projections(
234
- hist,
235
- xlabel=None,
236
- ylabel=None,
237
- ylabel_x_projection=None,
238
- xlabel_y_projection=None,
239
- colorbar_label=None,
240
- offset_x_labels=False,
241
- pcolormesh_kwargs=None,
242
- colorbar_kwargs=None,
243
- plot_hist_kwargs=None,
244
- figsize=(6, 6),
245
- ):
246
- """Plot a 2D histogram with projections on the x and y axes.
238
+ hist: bh.Histogram,
239
+ xlabel: str | None = None,
240
+ ylabel: str | None = None,
241
+ ylabel_x_projection: str | None = None,
242
+ xlabel_y_projection: str | None = None,
243
+ colorbar_label: str | None = None,
244
+ offset_x_labels: bool = False,
245
+ pcolormesh_kwargs: dict | None = None,
246
+ colorbar_kwargs: dict | None = None,
247
+ plot_hist_kwargs: dict | None = None,
248
+ figsize: tuple[float, float] = (6, 6),
249
+ ) -> tuple[plt.Figure, plt.Axes, plt.Axes, plt.Axes, plt.Axes]:
250
+ """
251
+ Plot a 2D histogram with projections on the x and y axes.
247
252
 
248
253
  Parameters
249
254
  ----------
250
- hist : 2D boost_histogram.Histogram
255
+ hist : bh.Histogram
251
256
  The 2D histogram to plot.
252
- xlabel : str, optional
257
+ xlabel : str | None, optional
253
258
  Label for the x axis. Default is None.
254
- ylabel : str, optional
259
+ ylabel : str | None, optional
255
260
  Label for the y axis. Default is None.
256
- ylabel_x_projection : str, optional
261
+ ylabel_x_projection : str | None, optional
257
262
  Label for the y axis of the x projection. Default is None.
258
- xlabel_y_projection : str, optional
263
+ xlabel_y_projection : str | None, optional
259
264
  Label for the x axis of the y projection. Default is None.
260
- colorbar_label : str, optional
265
+ colorbar_label : str | None, optional
261
266
  Label for the colorbar. Default is None.
262
267
  offset_x_labels : bool, optional
263
268
  Whether to offset the x labels to avoid overlapping with the exponent label (i.e. "10^X") of the axis. Default is False.
264
- pcolormesh_kwargs : dict, optional
269
+ pcolormesh_kwargs : dict | None, optional
265
270
  Keyword arguments for the pcolormesh call. Default is None.
266
- colorbar_kwargs : dict, optional
271
+ colorbar_kwargs : dict | None, optional
267
272
  Keyword arguments for the colorbar call. Default is None.
268
- plot_hist_kwargs : dict, optional
273
+ plot_hist_kwargs : dict | None, optional
269
274
  Keyword arguments for the plot_hist call (x and y projections). Default is None.
270
- figsize : tuple, optional
275
+ figsize : tuple[float, float], optional
271
276
  Figure size in inches. Default is (6, 6). To get square bins if the figure is not square shaped, be sure to set the bins and the ranges of the histogram according to the ratio of the figure width and height.
272
277
 
273
278
  Returns
@@ -364,13 +369,19 @@ def plot_2d_hist_with_projections(
364
369
  return fig, ax_2d, ax_x_projection, ax_y_projection, ax_colorbar
365
370
 
366
371
 
367
- def plot_error_hist(hist, ax, uncertainty_type="symmetrical", density=False, **kwargs):
372
+ def plot_error_hist(
373
+ hist: bh.Histogram,
374
+ ax: plt.Axes,
375
+ uncertainty_type: str = "symmetrical",
376
+ density: bool = False,
377
+ **kwargs,
378
+ ) -> None:
368
379
  """
369
380
  Create an errorbar plot from a boost histogram.
370
381
 
371
382
  Parameters
372
383
  ----------
373
- hist : boost_histogram.Histogram
384
+ hist : bh.Histogram
374
385
  The histogram to plot.
375
386
  ax : matplotlib.axes.Axes
376
387
  The Axes instance for plotting.
@@ -395,7 +406,9 @@ def plot_error_hist(hist, ax, uncertainty_type="symmetrical", density=False, **k
395
406
  if uncertainty_type == "symmetrical":
396
407
  kwargs.setdefault("yerr", np.sqrt(hist.variances()))
397
408
  else:
398
- uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(hist)
409
+ uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
410
+ hist, uncertainty_type
411
+ )
399
412
  kwargs.setdefault("yerr", [uncertainties_low, uncertainties_high])
400
413
 
401
414
  kwargs.setdefault("fmt", ".")
@@ -407,13 +420,13 @@ def plot_error_hist(hist, ax, uncertainty_type="symmetrical", density=False, **k
407
420
  )
408
421
 
409
422
 
410
- def plot_hist_uncertainties(hist, ax, **kwargs):
423
+ def plot_hist_uncertainties(hist: bh.Histogram, ax: plt.Axes, **kwargs) -> None:
411
424
  """
412
425
  Plot the symmetrical uncertainty, which is the Poisson standard deviation derived from the variance stored in the histogram, as a hatched area.
413
426
 
414
427
  Parameters
415
428
  ----------
416
- hist : boost_histogram.Histogram
429
+ hist : bh.Histogram
417
430
  The histogram from which we want to plot the uncertainties.
418
431
  ax : matplotlib.axes.Axes
419
432
  The Axes instance for plotting.
@@ -439,40 +452,40 @@ def plot_hist_uncertainties(hist, ax, **kwargs):
439
452
 
440
453
 
441
454
  def plot_two_hist_comparison(
442
- h1,
443
- h2,
444
- xlabel=None,
445
- ylabel=None,
446
- h1_label="h1",
447
- h2_label="h2",
448
- fig=None,
449
- ax_main=None,
450
- ax_comparison=None,
455
+ h1: bh.Histogram,
456
+ h2: bh.Histogram,
457
+ xlabel: str | None = None,
458
+ ylabel: str | None = None,
459
+ h1_label: str = "h1",
460
+ h2_label: str = "h2",
461
+ fig: plt.Figure | None = None,
462
+ ax_main: plt.Axes | None = None,
463
+ ax_comparison: plt.Axes | None = None,
451
464
  **comparison_kwargs,
452
- ):
465
+ ) -> tuple[plt.Figure, plt.Axes, plt.Axes]:
453
466
  """
454
467
  Compare two histograms.
455
468
 
456
469
  Parameters
457
470
  ----------
458
- h1 : boost_histogram.Histogram
471
+ h1 : bh.Histogram
459
472
  The first histogram to compare.
460
- h2 : boost_histogram.Histogram
473
+ h2 : bh.Histogram
461
474
  The second histogram to compare.
462
- xlabel : str, optional
475
+ xlabel : str | None, optional
463
476
  The label for the x-axis. Default is None.
464
- ylabel : str, optional
477
+ ylabel : str | None, optional
465
478
  The label for the y-axis. Default is None.
466
479
  h1_label : str, optional
467
480
  The label for the first histogram. Default is "h1".
468
481
  h2_label : str, optional
469
482
  The label for the second histogram. Default is "h2".
470
- fig : matplotlib.figure.Figure or None, optional
471
- The figure to use for the plot. If fig, ax_main and ax_comparison are None, a new figure will be created. Default is None.
472
- ax_main : matplotlib.axes.Axes or None, optional
473
- The main axes for the histogram comparison. If fig, ax_main and ax_comparison are None, a new axes will be created. Default is None.
474
- ax_comparison : matplotlib.axes.Axes or None, optional
475
- The axes for the comparison plot. If fig, ax_main and ax_comparison are None, a new axes will be created. Default is None.
483
+ fig : matplotlib.figure.Figure | None, optional
484
+ The figure to use for the plot. If fig, ax_main and ax_comparison are all None, a new figure will be created. Default is None.
485
+ ax_main : matplotlib.axes.Axes | None, optional
486
+ The main axes for the histogram comparison. If fig, ax_main and ax_comparison are all None, a new figure will be created. Default is None.
487
+ ax_comparison : matplotlib.axes.Axes | None, optional
488
+ The axes for the comparison plot. If fig, ax_main and ax_comparison are all None, a new figure will be created. Default is None.
476
489
  **comparison_kwargs : optional
477
490
  Arguments to be passed to plot_comparison(), including the choice of the comparison function and the treatment of the uncertainties (see documentation of plot_comparison() for details).
478
491
 
@@ -527,16 +540,16 @@ def plot_two_hist_comparison(
527
540
 
528
541
 
529
542
  def plot_comparison(
530
- h1,
531
- h2,
532
- ax,
533
- xlabel="",
534
- h1_label="h1",
535
- h2_label="h2",
536
- comparison="ratio",
537
- comparison_ylabel=None,
538
- comparison_ylim=None,
539
- h1_uncertainty_type="symmetrical",
543
+ h1: bh.Histogram,
544
+ h2: bh.Histogram,
545
+ ax: plt.Axes,
546
+ xlabel: str | None = None,
547
+ h1_label: str = "h1",
548
+ h2_label: str = "h2",
549
+ comparison: str = "ratio",
550
+ comparison_ylabel: str | None = None,
551
+ comparison_ylim: tuple[float, float] | None = None,
552
+ h1_uncertainty_type: str = "symmetrical",
540
553
  **plot_hist_kwargs,
541
554
  ):
542
555
  """
@@ -544,14 +557,14 @@ def plot_comparison(
544
557
 
545
558
  Parameters
546
559
  ----------
547
- h1 : boost_histogram.Histogram
560
+ h1 : bh.Histogram
548
561
  The first histogram for comparison.
549
- h2 : boost_histogram.Histogram
562
+ h2 : bh.Histogram
550
563
  The second histogram for comparison.
551
564
  ax : matplotlib.axes.Axes
552
565
  The axes to plot the comparison.
553
- xlabel : str, optional
554
- The label for the x-axis. Default is "".
566
+ xlabel : str | None, optional
567
+ The label for the x-axis. Default is None.
555
568
  h1_label : str, optional
556
569
  The label for the first histogram. Default is "h1".
557
570
  h2_label : str, optional
@@ -559,10 +572,10 @@ def plot_comparison(
559
572
  comparison : str, optional
560
573
  The type of comparison to plot ("ratio", "split_ratio", "pull", "difference", "relative_difference", "efficiency", or "asymmetry"). Default is "ratio".
561
574
  When the `split_ratio` option is used, both the h1 and h2 uncertainties are scaled down by the h2 bin contents, and the h2 adjusted uncertainties are shown separately as a hatched area.
562
- comparison_ylabel : str, optional
563
- The label for the y-axis. Default is the explicit formula used to compute the comparison plot.
564
- comparison_ylim : tuple or None, optional
565
- The y-axis limits for the comparison plot. Default is None. If None, standard y-axis limits are setup.
575
+ comparison_ylabel : str | None, optional
576
+ The label for the y-axis. If None, the label is the explicit formula used to compute the comparison plot. Default is None.
577
+ comparison_ylim : tuple[float, float] | None, optional
578
+ The y-axis limits for the comparison plot. If None, standard y-axis limits are setup. Default is None.
566
579
  h1_uncertainty_type : str, optional
567
580
  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".
568
581
  Asymmetrical uncertainties are not supported for the asymmetry and efficiency comparisons.
@@ -577,7 +590,6 @@ def plot_comparison(
577
590
  See Also
578
591
  --------
579
592
  plot_two_hist_comparison : Compare two histograms and plot the comparison.
580
-
581
593
  """
582
594
 
583
595
  h1_label = _get_math_text(h1_label)
@@ -626,13 +638,12 @@ def plot_comparison(
626
638
  ax.set_ylabel(r"$\frac{" + h1_label + "}{" + h2_label + "}$")
627
639
 
628
640
  if comparison == "split_ratio":
629
- np.seterr(divide="ignore", invalid="ignore")
630
- h2_scaled_uncertainties = np.where(
631
- h2.values() != 0,
632
- np.sqrt(h2.variances()) / h2.values(),
633
- np.nan,
634
- )
635
- np.seterr(divide="warn", invalid="warn")
641
+ with np.errstate(divide="ignore", invalid="ignore"):
642
+ h2_scaled_uncertainties = np.where(
643
+ h2.values() != 0,
644
+ np.sqrt(h2.variances()) / h2.values(),
645
+ np.nan,
646
+ )
636
647
  ax.bar(
637
648
  x=h2.axes[0].centers,
638
649
  bottom=np.nan_to_num(
@@ -683,7 +694,9 @@ def plot_comparison(
683
694
  return ax
684
695
 
685
696
 
686
- def savefig(fig, path, new_figsize=None):
697
+ def savefig(
698
+ fig: plt.Figure, path: str, new_figsize: tuple[float, float] | None = None
699
+ ) -> None:
687
700
  """
688
701
  Save a Matplotlib figure with consistent figsize, axes size and subplot spacing (experimental feature).
689
702
 
@@ -693,8 +706,8 @@ def savefig(fig, path, new_figsize=None):
693
706
  The Matplotlib figure to be saved.
694
707
  path : str
695
708
  The output file path where the figure will be saved.
696
- new_figsize : tuple, optional
697
- The new figsize as a (width, height) tuple. If None, the original figsize is preserved.
709
+ new_figsize : tuple[float, float] | None, optional
710
+ The new figsize as a (width, height) tuple. If None, the original figsize is preserved. Default is None.
698
711
 
699
712
  Returns
700
713
  -------
@@ -734,7 +747,7 @@ def savefig(fig, path, new_figsize=None):
734
747
  fig.savefig(path)
735
748
 
736
749
 
737
- def _get_math_text(text):
750
+ def _get_math_text(text: str) -> str:
738
751
  """
739
752
  Search for text between $ and return it.
740
753
 
@@ -754,7 +767,7 @@ def _get_math_text(text):
754
767
  return text
755
768
 
756
769
 
757
- def _get_model_type(components):
770
+ def _get_model_type(components: list) -> str:
758
771
  """
759
772
  Check that all components of a model are either all histograms or all functions
760
773
  and return the type of the model components.
@@ -782,64 +795,65 @@ def _get_model_type(components):
782
795
 
783
796
 
784
797
  def plot_model(
785
- stacked_components=None,
786
- stacked_labels=None,
787
- stacked_colors=None,
788
- unstacked_components=None,
789
- unstacked_labels=None,
790
- unstacked_colors=None,
791
- xlabel=None,
792
- ylabel=None,
793
- stacked_kwargs=None,
794
- unstacked_kwargs_list=None,
795
- model_sum_kwargs=None,
796
- function_range=None,
797
- model_uncertainty=True,
798
- model_uncertainty_label="Model stat. unc.",
799
- fig=None,
800
- ax=None,
801
- ):
798
+ stacked_components: list[bh.Histogram] | None = None,
799
+ stacked_labels: list[str] | None = None,
800
+ stacked_colors: list[str] | list[tuple[float, float, float]] | None = None,
801
+ unstacked_components: list[bh.Histogram] | None = None,
802
+ unstacked_labels: list[str] | list[None] | None = None,
803
+ unstacked_colors: (
804
+ list[str] | list[tuple[float, float, float]] | list[None] | None
805
+ ) = None,
806
+ xlabel: str | None = None,
807
+ ylabel: str | None = None,
808
+ stacked_kwargs: dict | None = None,
809
+ unstacked_kwargs_list: list[dict] | None = None,
810
+ model_sum_kwargs: dict | None = None,
811
+ function_range: tuple[float, float] | None = None,
812
+ model_uncertainty: bool = True,
813
+ model_uncertainty_label: str = "Model stat. unc.",
814
+ fig: plt.Figure | None = None,
815
+ ax: plt.Axes | None = None,
816
+ ) -> tuple[plt.Figure, plt.Axes]:
802
817
  """
803
818
  Plot model made of a collection of histograms.
804
819
 
805
820
  Parameters
806
821
  ----------
807
- stacked_components : list of boost_histogram.Histogram, optional
822
+ stacked_components : list[bh.Histogram] | None, optional
808
823
  The list of histograms to be stacked composing the model. Default is None.
809
- stacked_labels : list of str, optional
824
+ stacked_labels : list[str] | None, optional
810
825
  The labels of the model stacked components. Default is None.
811
- stacked_colors : list of str, optional
826
+ stacked_colors : list[str] | None, optional
812
827
  The colors of the model stacked components. Default is None.
813
- unstacked_components : list of boost_histogram.Histogram, optional
828
+ unstacked_components : list[bh.Histogram] | None, optional
814
829
  The list of histograms not to be stacked composing the model. Default is None.
815
- unstacked_labels : list of str, optional
830
+ unstacked_labels : list[str] | list[None] | None, optional
816
831
  The labels of the model unstacked components. Default is None.
817
- unstacked_colors : list of str, optional
832
+ unstacked_colors : list[str] | list[tuple[float, float, float]] | list[None] | None, optional
818
833
  The colors of the model unstacked components. Default is None.
819
- xlabel : str, optional
834
+ xlabel : str | None, optional
820
835
  The label for the x-axis. Default is None.
821
- ylabel : str, optional
836
+ ylabel : str | None, optional
822
837
  The label for the y-axis. Default is None.
823
- stacked_kwargs : dict, optional
838
+ stacked_kwargs : dict | None, optional
824
839
  The keyword arguments used when plotting the stacked components in plot_hist() or plot_function(), one of which is called only once. Default is None.
825
- unstacked_kwargs_list : list of dict, optional
840
+ unstacked_kwargs_list : list[dict] | None, optional
826
841
  The list of keyword arguments used when plotting the unstacked components in plot_hist() or plot_function(), one of which is called once for each unstacked component. Default is None.
827
- model_sum_kwargs : dict, optional
842
+ model_sum_kwargs : dict | None, optional
828
843
  The keyword arguments for the plot_hist() function for the sum of the model components.
829
844
  Has no effect if all the model components are stacked or if the model is one unstacked element.
830
845
  The special keyword "show" can be used with a boolean to specify whether to show or not the sum of the model components.
831
846
  Default is None. If None is provided, this is set to {"show": True, "label": "Model", "color": "navy"}.
832
- function_range : tuple, optional (mandatory if the model is made of functions)
833
- The range for the x-axis if the model is made of functions.
847
+ function_range : tuple[float, float] | None, optional (mandatory if the model is made of functions)
848
+ The range for the x-axis if the model is made of functions. Default is None.
834
849
  model_uncertainty : bool, optional
835
850
  If False, set the model uncertainties to zeros. Default is True.
836
851
  model_uncertainty_label : str, optional
837
852
  The label for the model uncertainties. Default is "Model stat. unc.".
838
- fig : matplotlib.figure.Figure or None, optional
839
- The Figure object to use for the plot. Create a new one if none is provided.
840
- ax : matplotlib.axes.Axes or None, optional
841
- The Axes object to use for the plot. Create a new one if none is provided.
842
-
853
+ fig : matplotlib.figure.Figure | None, optional
854
+ The Figure object to use for the plot. If fig and ax are all None, a new figure will be created. Default is None.
855
+ ax : matplotlib.axes.Axes | None, optional
856
+ The Axes object to use for the plot. If fig and ax are all None, a new figure will be created. Default is None.
843
857
 
844
858
  Returns
845
859
  -------
@@ -847,8 +861,8 @@ def plot_model(
847
861
  The Figure object containing the plot.
848
862
  ax : matplotlib.axes.Axes
849
863
  The Axes object containing the plot.
850
-
851
864
  """
865
+
852
866
  if model_sum_kwargs is None:
853
867
  model_sum_kwargs = {"show": True, "label": "Model", "color": "navy"}
854
868
  if unstacked_kwargs_list is None:
@@ -1000,58 +1014,58 @@ def plot_model(
1000
1014
 
1001
1015
 
1002
1016
  def plot_data_model_comparison(
1003
- data_hist,
1004
- stacked_components=None,
1005
- stacked_labels=None,
1006
- stacked_colors=None,
1007
- unstacked_components=None,
1008
- unstacked_labels=None,
1009
- unstacked_colors=None,
1010
- xlabel=None,
1011
- ylabel=None,
1012
- data_label="Data",
1013
- stacked_kwargs=None,
1014
- unstacked_kwargs_list=None,
1015
- model_sum_kwargs=None,
1016
- model_uncertainty=True,
1017
- model_uncertainty_label="Model stat. unc.",
1018
- data_uncertainty_type="asymmetrical",
1019
- fig=None,
1020
- ax_main=None,
1021
- ax_comparison=None,
1022
- plot_only=None,
1017
+ data_hist: bh.Histogram,
1018
+ stacked_components: list[bh.Histogram] | None = None,
1019
+ stacked_labels: list[str] | None = None,
1020
+ stacked_colors: list[str] | list[tuple[float, float, float]] | None = None,
1021
+ unstacked_components: list[bh.Histogram] | None = None,
1022
+ unstacked_labels: list[str] | None = None,
1023
+ unstacked_colors: list[str] | list[tuple[float, float, float]] | None = None,
1024
+ xlabel: str | None = None,
1025
+ ylabel: str | None = None,
1026
+ data_label: str = "Data",
1027
+ stacked_kwargs: dict | None = None,
1028
+ unstacked_kwargs_list: list[dict] | None = None,
1029
+ model_sum_kwargs: dict | None = None,
1030
+ model_uncertainty: bool = True,
1031
+ model_uncertainty_label: str = "Model stat. unc.",
1032
+ data_uncertainty_type: str = "asymmetrical",
1033
+ fig: plt.Figure | None = None,
1034
+ ax_main: plt.Axes | None = None,
1035
+ ax_comparison: plt.Axes | None = None,
1036
+ plot_only: str | None = None,
1023
1037
  **comparison_kwargs,
1024
- ):
1038
+ ) -> tuple[plt.Figure, plt.Axes, plt.Axes]:
1025
1039
  """
1026
1040
  Compare data to model. The data uncertainties are computed using the Poisson confidence interval.
1027
1041
 
1028
1042
  Parameters
1029
1043
  ----------
1030
- data_hist : boost_histogram.Histogram
1044
+ data_hist : bh.Histogram
1031
1045
  The histogram for the data.
1032
- stacked_components : list of boost_histogram.Histogram, optional
1046
+ stacked_components : list[bh.Histogram] | None, optional
1033
1047
  The list of histograms to be stacked composing the model. Default is None.
1034
- stacked_labels : list of str, optional
1048
+ stacked_labels : list[str] | None, optional
1035
1049
  The labels of the model stacked components. Default is None.
1036
- stacked_colors : list of str, optional
1050
+ stacked_colors : list[str] | None, optional
1037
1051
  The colors of the model stacked components. Default is None.
1038
- unstacked_components : list of boost_histogram.Histogram, optional
1052
+ unstacked_components : list[bh.Histogram] | None, optional
1039
1053
  The list of histograms not to be stacked composing the model. Default is None.
1040
- unstacked_labels : list of str, optional
1054
+ unstacked_labels : list[str] | None, optional
1041
1055
  The labels of the model unstacked components. Default is None.
1042
- unstacked_colors : list of str, optional
1056
+ unstacked_colors : list[str] | None, optional
1043
1057
  The colors of the model unstacked components. Default is None.
1044
- xlabel : str, optional
1058
+ xlabel : str | None, optional
1045
1059
  The label for the x-axis. Default is None.
1046
- ylabel : str, optional
1060
+ ylabel : str | None, optional
1047
1061
  The label for the y-axis. Default is None.
1048
1062
  data_label : str, optional
1049
1063
  The label for the data. Default is "Data".
1050
- stacked_kwargs : dict, optional
1064
+ stacked_kwargs : dict | None, optional
1051
1065
  The keyword arguments used when plotting the stacked components in plot_hist() or plot_function(), one of which is called only once. Default is None.
1052
- unstacked_kwargs_list : list of dict, optional
1066
+ unstacked_kwargs_list : list[dict] | None, optional
1053
1067
  The list of keyword arguments used when plotting the unstacked components in plot_hist() or plot_function(), one of which is called once for each unstacked component. Default is None.
1054
- model_sum_kwargs : dict, optional
1068
+ model_sum_kwargs : dict | None, optional
1055
1069
  The keyword arguments for the plot_hist() function for the sum of the model components.
1056
1070
  Has no effect if all the model components are stacked or if the model is one unstacked element.
1057
1071
  The special keyword "show" can be used with a boolean to specify whether to show or not the sum of the model components.
@@ -1062,16 +1076,17 @@ def plot_data_model_comparison(
1062
1076
  The label for the model uncertainties. Default is "Model stat. unc.".
1063
1077
  data_uncertainty_type : str, optional
1064
1078
  What kind of bin uncertainty to use for data_hist: "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 "asymmetrical".
1065
- fig : matplotlib.figure.Figure or None, optional
1066
- The figure to use for the plot. If fig, ax_main and ax_comparison are None, a new figure will be created. Default is None.
1067
- ax_main : matplotlib.axes.Axes or None, optional
1068
- The main axes for the histogram comparison. If fig, ax_main and ax_comparison are None, a new axes will be created. Default is None.
1069
- ax_comparison : matplotlib.axes.Axes or None, optional
1070
- The axes for the comparison plot. If fig, ax_main and ax_comparison are None, a new axes will be created. Default is None.
1071
- plot_only : str, optional
1079
+ fig : matplotlib.figure.Figure | None, optional
1080
+ The figure to use for the plot. If fig, ax_main and ax_comparison are all None, a new figure will be created. Default is None.
1081
+ ax_main : matplotlib.axes.Axes | None, optional
1082
+ The main axes for the histogram comparison. If fig, ax_main and ax_comparison are all None, a new figure will be created. Default is None.
1083
+ ax_comparison : matplotlib.axes.Axes | None, optional
1084
+ The axes for the comparison plot. If fig, ax_main and ax_comparison are all None, a new figure will be created. Default is None.
1085
+ plot_only : str | None, optional
1072
1086
  If "ax_main" or "ax_comparison", only the main or comparison axis is plotted on the figure. Both axes are plotted if None is specified, which is the default. This can only be used when fig, ax_main and ax_comparison are not provided by the user.
1073
1087
  **comparison_kwargs : optional
1074
- Arguments to be passed to plot_comparison(), including the choice of the comparison function and the treatment of the uncertainties (see documentation of plot_comparison() for details). If they are not provided explicitly, the following arguments are passed by default: h1_label="Data", h2_label="Pred.", comparison="split_ratio".
1088
+ Arguments to be passed to plot_comparison(), including the choice of the comparison function and the treatment of the uncertainties (see documentation of plot_comparison() for details).
1089
+ If they are not provided explicitly, the following arguments are passed by default: h1_label="Data", h2_label="Pred.", comparison="split_ratio".
1075
1090
 
1076
1091
  Returns
1077
1092
  -------
@@ -1148,7 +1163,7 @@ def plot_data_model_comparison(
1148
1163
  stacked_kwargs=stacked_kwargs,
1149
1164
  unstacked_kwargs_list=unstacked_kwargs_list,
1150
1165
  model_sum_kwargs=model_sum_kwargs,
1151
- function_range=[data_hist.axes[0].edges[0], data_hist.axes[0].edges[-1]],
1166
+ function_range=(data_hist.axes[0].edges[0], data_hist.axes[0].edges[-1]),
1152
1167
  model_uncertainty=model_uncertainty,
1153
1168
  model_uncertainty_label=model_uncertainty_label,
1154
1169
  fig=fig,