plothist 1.4.0__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 (64) hide show
  1. plothist/_version.py +2 -2
  2. plothist/comparison.py +111 -105
  3. plothist/examples/1d_hist/1d_comparison_asymmetry.py +37 -0
  4. plothist/examples/1d_hist/1d_comparison_difference.py +40 -0
  5. plothist/examples/1d_hist/1d_comparison_efficiency.py +37 -0
  6. plothist/examples/1d_hist/1d_comparison_only_efficiency.py +33 -0
  7. plothist/examples/1d_hist/1d_comparison_pull.py +37 -0
  8. plothist/examples/1d_hist/1d_comparison_ratio.py +37 -0
  9. plothist/examples/1d_hist/1d_comparison_relative_difference.py +37 -0
  10. plothist/examples/1d_hist/1d_comparison_split_ratio.py +37 -0
  11. plothist/examples/1d_hist/1d_elt1.py +38 -0
  12. plothist/examples/1d_hist/1d_elt1_stacked.py +45 -0
  13. plothist/examples/1d_hist/1d_elt2.py +33 -0
  14. plothist/examples/1d_hist/1d_hist_simple.py +28 -0
  15. plothist/examples/1d_hist/1d_int_category.py +41 -0
  16. plothist/examples/1d_hist/1d_profile.py +33 -0
  17. plothist/examples/1d_hist/1d_side_by_side.py +58 -0
  18. plothist/examples/1d_hist/1d_str_category.py +41 -0
  19. plothist/examples/1d_hist/README.rst +4 -0
  20. plothist/examples/2d_hist/2d_hist_correlations.py +65 -0
  21. plothist/examples/2d_hist/2d_hist_simple.py +28 -0
  22. plothist/examples/2d_hist/2d_hist_simple_discrete_colormap.py +42 -0
  23. plothist/examples/2d_hist/2d_hist_uneven.py +28 -0
  24. plothist/examples/2d_hist/2d_hist_with_projections.py +36 -0
  25. plothist/examples/2d_hist/README.rst +4 -0
  26. plothist/examples/README.rst +7 -0
  27. plothist/examples/advanced/1d_comparison_advanced.py +87 -0
  28. plothist/examples/advanced/1d_side_by_side_with_numbers.py +81 -0
  29. plothist/examples/advanced/README.rst +4 -0
  30. plothist/examples/advanced/asymmetry_comparison_advanced.py +133 -0
  31. plothist/examples/advanced/model_examples_flatten2D.py +86 -0
  32. plothist/examples/func_1d/README.rst +4 -0
  33. plothist/examples/func_1d/fct_1d.py +27 -0
  34. plothist/examples/func_1d/fct_1d_stacked.py +42 -0
  35. plothist/examples/model_ex/README.rst +4 -0
  36. plothist/examples/model_ex/model_all_comparisons.py +103 -0
  37. plothist/examples/model_ex/model_all_comparisons_no_model_unc.py +115 -0
  38. plothist/examples/model_ex/model_examples_pull.py +56 -0
  39. plothist/examples/model_ex/model_examples_pull_no_model_unc.py +59 -0
  40. plothist/examples/model_ex/model_examples_stacked.py +74 -0
  41. plothist/examples/model_ex/model_examples_stacked_unstacked.py +60 -0
  42. plothist/examples/model_ex/model_examples_unstacked.py +57 -0
  43. plothist/examples/model_ex/model_with_stacked_and_unstacked_function_components.py +50 -0
  44. plothist/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py +69 -0
  45. plothist/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py +61 -0
  46. plothist/examples/utility/README.rst +4 -0
  47. plothist/examples/utility/add_text_example.py +39 -0
  48. plothist/examples/utility/color_palette_hists.py +94 -0
  49. plothist/examples/utility/color_palette_squares.py +100 -0
  50. plothist/examples/utility/matplotlib_vs_plothist_style.py +63 -0
  51. plothist/histogramming.py +60 -39
  52. plothist/plothist_style.py +54 -57
  53. plothist/plotters.py +207 -194
  54. plothist/test_helpers.py +43 -0
  55. plothist/variable_registry.py +46 -30
  56. {plothist-1.4.0.dist-info → plothist-1.5.0.dist-info}/METADATA +1 -1
  57. plothist-1.5.0.dist-info/RECORD +63 -0
  58. plothist/scripts/__init__.py +0 -3
  59. plothist/scripts/make_examples.py +0 -209
  60. plothist-1.4.0.dist-info/RECORD +0 -17
  61. plothist-1.4.0.dist-info/entry_points.txt +0 -2
  62. {plothist-1.4.0.dist-info → plothist-1.5.0.dist-info}/WHEEL +0 -0
  63. {plothist-1.4.0.dist-info → plothist-1.5.0.dist-info}/licenses/AUTHORS.md +0 -0
  64. {plothist-1.4.0.dist-info → plothist-1.5.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.
@@ -407,13 +418,13 @@ def plot_error_hist(hist, ax, uncertainty_type="symmetrical", density=False, **k
407
418
  )
408
419
 
409
420
 
410
- def plot_hist_uncertainties(hist, ax, **kwargs):
421
+ def plot_hist_uncertainties(hist: bh.Histogram, ax: plt.Axes, **kwargs) -> None:
411
422
  """
412
423
  Plot the symmetrical uncertainty, which is the Poisson standard deviation derived from the variance stored in the histogram, as a hatched area.
413
424
 
414
425
  Parameters
415
426
  ----------
416
- hist : boost_histogram.Histogram
427
+ hist : bh.Histogram
417
428
  The histogram from which we want to plot the uncertainties.
418
429
  ax : matplotlib.axes.Axes
419
430
  The Axes instance for plotting.
@@ -439,40 +450,40 @@ def plot_hist_uncertainties(hist, ax, **kwargs):
439
450
 
440
451
 
441
452
  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,
453
+ h1: bh.Histogram,
454
+ h2: bh.Histogram,
455
+ xlabel: str | None = None,
456
+ ylabel: str | None = None,
457
+ h1_label: str = "h1",
458
+ h2_label: str = "h2",
459
+ fig: plt.Figure | None = None,
460
+ ax_main: plt.Axes | None = None,
461
+ ax_comparison: plt.Axes | None = None,
451
462
  **comparison_kwargs,
452
- ):
463
+ ) -> tuple[plt.Figure, plt.Axes, plt.Axes]:
453
464
  """
454
465
  Compare two histograms.
455
466
 
456
467
  Parameters
457
468
  ----------
458
- h1 : boost_histogram.Histogram
469
+ h1 : bh.Histogram
459
470
  The first histogram to compare.
460
- h2 : boost_histogram.Histogram
471
+ h2 : bh.Histogram
461
472
  The second histogram to compare.
462
- xlabel : str, optional
473
+ xlabel : str | None, optional
463
474
  The label for the x-axis. Default is None.
464
- ylabel : str, optional
475
+ ylabel : str | None, optional
465
476
  The label for the y-axis. Default is None.
466
477
  h1_label : str, optional
467
478
  The label for the first histogram. Default is "h1".
468
479
  h2_label : str, optional
469
480
  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.
481
+ fig : matplotlib.figure.Figure | None, optional
482
+ 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.
483
+ ax_main : matplotlib.axes.Axes | None, optional
484
+ 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.
485
+ ax_comparison : matplotlib.axes.Axes | None, optional
486
+ 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
487
  **comparison_kwargs : optional
477
488
  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
489
 
@@ -527,16 +538,16 @@ def plot_two_hist_comparison(
527
538
 
528
539
 
529
540
  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",
541
+ h1: bh.Histogram,
542
+ h2: bh.Histogram,
543
+ ax: plt.Axes,
544
+ xlabel: str | None = None,
545
+ h1_label: str = "h1",
546
+ h2_label: str = "h2",
547
+ comparison: str = "ratio",
548
+ comparison_ylabel: str | None = None,
549
+ comparison_ylim: tuple[float, float] | None = None,
550
+ h1_uncertainty_type: str = "symmetrical",
540
551
  **plot_hist_kwargs,
541
552
  ):
542
553
  """
@@ -544,14 +555,14 @@ def plot_comparison(
544
555
 
545
556
  Parameters
546
557
  ----------
547
- h1 : boost_histogram.Histogram
558
+ h1 : bh.Histogram
548
559
  The first histogram for comparison.
549
- h2 : boost_histogram.Histogram
560
+ h2 : bh.Histogram
550
561
  The second histogram for comparison.
551
562
  ax : matplotlib.axes.Axes
552
563
  The axes to plot the comparison.
553
- xlabel : str, optional
554
- The label for the x-axis. Default is "".
564
+ xlabel : str | None, optional
565
+ The label for the x-axis. Default is None.
555
566
  h1_label : str, optional
556
567
  The label for the first histogram. Default is "h1".
557
568
  h2_label : str, optional
@@ -559,10 +570,10 @@ def plot_comparison(
559
570
  comparison : str, optional
560
571
  The type of comparison to plot ("ratio", "split_ratio", "pull", "difference", "relative_difference", "efficiency", or "asymmetry"). Default is "ratio".
561
572
  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.
573
+ comparison_ylabel : str | None, optional
574
+ The label for the y-axis. If None, the label is the explicit formula used to compute the comparison plot. Default is None.
575
+ comparison_ylim : tuple[float, float] | None, optional
576
+ The y-axis limits for the comparison plot. If None, standard y-axis limits are setup. Default is None.
566
577
  h1_uncertainty_type : str, optional
567
578
  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
579
  Asymmetrical uncertainties are not supported for the asymmetry and efficiency comparisons.
@@ -577,7 +588,6 @@ def plot_comparison(
577
588
  See Also
578
589
  --------
579
590
  plot_two_hist_comparison : Compare two histograms and plot the comparison.
580
-
581
591
  """
582
592
 
583
593
  h1_label = _get_math_text(h1_label)
@@ -626,13 +636,12 @@ def plot_comparison(
626
636
  ax.set_ylabel(r"$\frac{" + h1_label + "}{" + h2_label + "}$")
627
637
 
628
638
  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")
639
+ with np.errstate(divide="ignore", invalid="ignore"):
640
+ h2_scaled_uncertainties = np.where(
641
+ h2.values() != 0,
642
+ np.sqrt(h2.variances()) / h2.values(),
643
+ np.nan,
644
+ )
636
645
  ax.bar(
637
646
  x=h2.axes[0].centers,
638
647
  bottom=np.nan_to_num(
@@ -683,7 +692,9 @@ def plot_comparison(
683
692
  return ax
684
693
 
685
694
 
686
- def savefig(fig, path, new_figsize=None):
695
+ def savefig(
696
+ fig: plt.Figure, path: str, new_figsize: tuple[float, float] | None = None
697
+ ) -> None:
687
698
  """
688
699
  Save a Matplotlib figure with consistent figsize, axes size and subplot spacing (experimental feature).
689
700
 
@@ -693,8 +704,8 @@ def savefig(fig, path, new_figsize=None):
693
704
  The Matplotlib figure to be saved.
694
705
  path : str
695
706
  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.
707
+ new_figsize : tuple[float, float] | None, optional
708
+ The new figsize as a (width, height) tuple. If None, the original figsize is preserved. Default is None.
698
709
 
699
710
  Returns
700
711
  -------
@@ -734,7 +745,7 @@ def savefig(fig, path, new_figsize=None):
734
745
  fig.savefig(path)
735
746
 
736
747
 
737
- def _get_math_text(text):
748
+ def _get_math_text(text: str) -> str:
738
749
  """
739
750
  Search for text between $ and return it.
740
751
 
@@ -754,7 +765,7 @@ def _get_math_text(text):
754
765
  return text
755
766
 
756
767
 
757
- def _get_model_type(components):
768
+ def _get_model_type(components: list) -> str:
758
769
  """
759
770
  Check that all components of a model are either all histograms or all functions
760
771
  and return the type of the model components.
@@ -782,64 +793,65 @@ def _get_model_type(components):
782
793
 
783
794
 
784
795
  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
- ):
796
+ stacked_components: list[bh.Histogram] | None = None,
797
+ stacked_labels: list[str] | None = None,
798
+ stacked_colors: list[str] | list[tuple[float, float, float]] | None = None,
799
+ unstacked_components: list[bh.Histogram] | None = None,
800
+ unstacked_labels: list[str] | list[None] | None = None,
801
+ unstacked_colors: (
802
+ list[str] | list[tuple[float, float, float]] | list[None] | None
803
+ ) = None,
804
+ xlabel: str | None = None,
805
+ ylabel: str | None = None,
806
+ stacked_kwargs: dict | None = None,
807
+ unstacked_kwargs_list: list[dict] | None = None,
808
+ model_sum_kwargs: dict | None = None,
809
+ function_range: tuple[float, float] | None = None,
810
+ model_uncertainty: bool = True,
811
+ model_uncertainty_label: str = "Model stat. unc.",
812
+ fig: plt.Figure | None = None,
813
+ ax: plt.Axes | None = None,
814
+ ) -> tuple[plt.Figure, plt.Axes]:
802
815
  """
803
816
  Plot model made of a collection of histograms.
804
817
 
805
818
  Parameters
806
819
  ----------
807
- stacked_components : list of boost_histogram.Histogram, optional
820
+ stacked_components : list[bh.Histogram] | None, optional
808
821
  The list of histograms to be stacked composing the model. Default is None.
809
- stacked_labels : list of str, optional
822
+ stacked_labels : list[str] | None, optional
810
823
  The labels of the model stacked components. Default is None.
811
- stacked_colors : list of str, optional
824
+ stacked_colors : list[str] | None, optional
812
825
  The colors of the model stacked components. Default is None.
813
- unstacked_components : list of boost_histogram.Histogram, optional
826
+ unstacked_components : list[bh.Histogram] | None, optional
814
827
  The list of histograms not to be stacked composing the model. Default is None.
815
- unstacked_labels : list of str, optional
828
+ unstacked_labels : list[str] | list[None] | None, optional
816
829
  The labels of the model unstacked components. Default is None.
817
- unstacked_colors : list of str, optional
830
+ unstacked_colors : list[str] | list[tuple[float, float, float]] | list[None] | None, optional
818
831
  The colors of the model unstacked components. Default is None.
819
- xlabel : str, optional
832
+ xlabel : str | None, optional
820
833
  The label for the x-axis. Default is None.
821
- ylabel : str, optional
834
+ ylabel : str | None, optional
822
835
  The label for the y-axis. Default is None.
823
- stacked_kwargs : dict, optional
836
+ stacked_kwargs : dict | None, optional
824
837
  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
838
+ unstacked_kwargs_list : list[dict] | None, optional
826
839
  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
840
+ model_sum_kwargs : dict | None, optional
828
841
  The keyword arguments for the plot_hist() function for the sum of the model components.
829
842
  Has no effect if all the model components are stacked or if the model is one unstacked element.
830
843
  The special keyword "show" can be used with a boolean to specify whether to show or not the sum of the model components.
831
844
  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.
845
+ function_range : tuple[float, float] | None, optional (mandatory if the model is made of functions)
846
+ The range for the x-axis if the model is made of functions. Default is None.
834
847
  model_uncertainty : bool, optional
835
848
  If False, set the model uncertainties to zeros. Default is True.
836
849
  model_uncertainty_label : str, optional
837
850
  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
-
851
+ fig : matplotlib.figure.Figure | None, optional
852
+ The Figure object to use for the plot. If fig and ax are all None, a new figure will be created. Default is None.
853
+ ax : matplotlib.axes.Axes | None, optional
854
+ 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
855
 
844
856
  Returns
845
857
  -------
@@ -847,8 +859,8 @@ def plot_model(
847
859
  The Figure object containing the plot.
848
860
  ax : matplotlib.axes.Axes
849
861
  The Axes object containing the plot.
850
-
851
862
  """
863
+
852
864
  if model_sum_kwargs is None:
853
865
  model_sum_kwargs = {"show": True, "label": "Model", "color": "navy"}
854
866
  if unstacked_kwargs_list is None:
@@ -1000,58 +1012,58 @@ def plot_model(
1000
1012
 
1001
1013
 
1002
1014
  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,
1015
+ data_hist: bh.Histogram,
1016
+ stacked_components: list[bh.Histogram] | None = None,
1017
+ stacked_labels: list[str] | None = None,
1018
+ stacked_colors: list[str] | list[tuple[float, float, float]] | None = None,
1019
+ unstacked_components: list[bh.Histogram] | None = None,
1020
+ unstacked_labels: list[str] | None = None,
1021
+ unstacked_colors: list[str] | list[tuple[float, float, float]] | None = None,
1022
+ xlabel: str | None = None,
1023
+ ylabel: str | None = None,
1024
+ data_label: str = "Data",
1025
+ stacked_kwargs: dict | None = None,
1026
+ unstacked_kwargs_list: list[dict] | None = None,
1027
+ model_sum_kwargs: dict | None = None,
1028
+ model_uncertainty: bool = True,
1029
+ model_uncertainty_label: str = "Model stat. unc.",
1030
+ data_uncertainty_type: str = "asymmetrical",
1031
+ fig: plt.Figure | None = None,
1032
+ ax_main: plt.Axes | None = None,
1033
+ ax_comparison: plt.Axes | None = None,
1034
+ plot_only: str | None = None,
1023
1035
  **comparison_kwargs,
1024
- ):
1036
+ ) -> tuple[plt.Figure, plt.Axes, plt.Axes]:
1025
1037
  """
1026
1038
  Compare data to model. The data uncertainties are computed using the Poisson confidence interval.
1027
1039
 
1028
1040
  Parameters
1029
1041
  ----------
1030
- data_hist : boost_histogram.Histogram
1042
+ data_hist : bh.Histogram
1031
1043
  The histogram for the data.
1032
- stacked_components : list of boost_histogram.Histogram, optional
1044
+ stacked_components : list[bh.Histogram] | None, optional
1033
1045
  The list of histograms to be stacked composing the model. Default is None.
1034
- stacked_labels : list of str, optional
1046
+ stacked_labels : list[str] | None, optional
1035
1047
  The labels of the model stacked components. Default is None.
1036
- stacked_colors : list of str, optional
1048
+ stacked_colors : list[str] | None, optional
1037
1049
  The colors of the model stacked components. Default is None.
1038
- unstacked_components : list of boost_histogram.Histogram, optional
1050
+ unstacked_components : list[bh.Histogram] | None, optional
1039
1051
  The list of histograms not to be stacked composing the model. Default is None.
1040
- unstacked_labels : list of str, optional
1052
+ unstacked_labels : list[str] | None, optional
1041
1053
  The labels of the model unstacked components. Default is None.
1042
- unstacked_colors : list of str, optional
1054
+ unstacked_colors : list[str] | None, optional
1043
1055
  The colors of the model unstacked components. Default is None.
1044
- xlabel : str, optional
1056
+ xlabel : str | None, optional
1045
1057
  The label for the x-axis. Default is None.
1046
- ylabel : str, optional
1058
+ ylabel : str | None, optional
1047
1059
  The label for the y-axis. Default is None.
1048
1060
  data_label : str, optional
1049
1061
  The label for the data. Default is "Data".
1050
- stacked_kwargs : dict, optional
1062
+ stacked_kwargs : dict | None, optional
1051
1063
  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
1064
+ unstacked_kwargs_list : list[dict] | None, optional
1053
1065
  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
1066
+ model_sum_kwargs : dict | None, optional
1055
1067
  The keyword arguments for the plot_hist() function for the sum of the model components.
1056
1068
  Has no effect if all the model components are stacked or if the model is one unstacked element.
1057
1069
  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 +1074,17 @@ def plot_data_model_comparison(
1062
1074
  The label for the model uncertainties. Default is "Model stat. unc.".
1063
1075
  data_uncertainty_type : str, optional
1064
1076
  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
1077
+ fig : matplotlib.figure.Figure | None, optional
1078
+ 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.
1079
+ ax_main : matplotlib.axes.Axes | None, optional
1080
+ 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.
1081
+ ax_comparison : matplotlib.axes.Axes | None, optional
1082
+ 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.
1083
+ plot_only : str | None, optional
1072
1084
  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
1085
  **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".
1086
+ 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).
1087
+ If they are not provided explicitly, the following arguments are passed by default: h1_label="Data", h2_label="Pred.", comparison="split_ratio".
1075
1088
 
1076
1089
  Returns
1077
1090
  -------
@@ -1148,7 +1161,7 @@ def plot_data_model_comparison(
1148
1161
  stacked_kwargs=stacked_kwargs,
1149
1162
  unstacked_kwargs_list=unstacked_kwargs_list,
1150
1163
  model_sum_kwargs=model_sum_kwargs,
1151
- function_range=[data_hist.axes[0].edges[0], data_hist.axes[0].edges[-1]],
1164
+ function_range=(data_hist.axes[0].edges[0], data_hist.axes[0].edges[-1]),
1152
1165
  model_uncertainty=model_uncertainty,
1153
1166
  model_uncertainty_label=model_uncertainty_label,
1154
1167
  fig=fig,