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
@@ -1,10 +1,11 @@
1
+ from __future__ import annotations
2
+
3
+ import matplotlib as mpl
1
4
  import matplotlib.pyplot as plt
2
5
  import numpy as np
3
- import matplotlib as mpl
4
- from importlib.resources import files
5
6
 
6
7
 
7
- def set_style(style="default"):
8
+ def set_style(style: str = "default") -> None:
8
9
  """
9
10
  Set the plothist style.
10
11
 
@@ -29,22 +30,21 @@ def set_style(style="default"):
29
30
  available_styles = ["default"]
30
31
 
31
32
  if style in available_styles:
32
- style_file = files("plothist").joinpath(f"{style}_style.mplstyle")
33
- plt.style.use(style_file)
33
+ plt.style.use(f"plothist.{style}_style")
34
34
  else:
35
35
  raise ValueError(f"{style} not in the available styles: {available_styles}")
36
36
 
37
37
 
38
38
  def cubehelix_palette(
39
- ncolors=7,
40
- start=1.5,
41
- rotation=1.5,
42
- gamma=1.0,
43
- hue=0.8,
44
- lightest=0.8,
45
- darkest=0.3,
46
- reverse=True,
47
- ):
39
+ ncolors: int = 7,
40
+ start: float = 1.5,
41
+ rotation: float = 1.5,
42
+ gamma: float = 1.0,
43
+ hue: float = 0.8,
44
+ lightest: float = 0.8,
45
+ darkest: float = 0.3,
46
+ reverse: bool = True,
47
+ ) -> list[tuple[float, float, float]]:
48
48
  """
49
49
  Make a sequential palette from the cubehelix system, in which the perceived brightness is linearly increasing.
50
50
  This code is adapted from seaborn, which implements equation (2) of reference [1] below.
@@ -72,10 +72,9 @@ def cubehelix_palette(
72
72
 
73
73
  Returns
74
74
  -------
75
- list of RGB tuples
75
+ list[tuple[float, float, float]]
76
76
  The generated palette of colors represented as a list of RGB tuples.
77
77
 
78
-
79
78
  References
80
79
  ----------
81
80
  [1] Green, D. A. (2011). "A colour scheme for the display of astronomical
@@ -87,7 +86,7 @@ def cubehelix_palette(
87
86
  # Adapted from matplotlib
88
87
  def color(lambda_):
89
88
  # emphasise either low intensity values (gamma < 1),
90
- # or high intensity values (γ > 1)
89
+ # or high intensity values (gamma > 1)
91
90
  lambda_gamma = lambda_**gamma
92
91
 
93
92
  # Angle and amplitude for the deviation
@@ -116,7 +115,9 @@ def cubehelix_palette(
116
115
  return pal
117
116
 
118
117
 
119
- def get_color_palette(cmap, N):
118
+ def get_color_palette(
119
+ cmap: str, N: int
120
+ ) -> list[str] | list[tuple[float, float, float]]:
120
121
  """
121
122
  Get N different colors from a chosen colormap.
122
123
 
@@ -129,8 +130,9 @@ def get_color_palette(cmap, N):
129
130
 
130
131
  Returns
131
132
  -------
132
- list
133
- A list of RGB color tuples sampled from the colormap.
133
+ list[str] or list[tuple[float, float, float]]
134
+ A list of colors. If "ggplot" is selected, returns a list of hex color strings.
135
+ Otherwise, returns a list of RGB color tuples.
134
136
 
135
137
  References
136
138
  ----------
@@ -159,7 +161,7 @@ def get_color_palette(cmap, N):
159
161
  "#FFB5B8",
160
162
  ][0:N]
161
163
 
162
- elif cmap == "cubehelix":
164
+ if cmap == "cubehelix":
163
165
  return cubehelix_palette(N)
164
166
 
165
167
  if N < 2:
@@ -171,7 +173,7 @@ def get_color_palette(cmap, N):
171
173
  return plt_cmap(np.linspace(0, 1, N))
172
174
 
173
175
 
174
- def set_fitting_ylabel_fontsize(ax):
176
+ def set_fitting_ylabel_fontsize(ax: plt.Axes) -> float:
175
177
  """
176
178
  Get the suitable font size for a ylabel text that fits within the plot's y-axis limits.
177
179
 
@@ -187,9 +189,8 @@ def set_fitting_ylabel_fontsize(ax):
187
189
  """
188
190
  ylabel_fontsize = ax.yaxis.get_label().get_fontsize()
189
191
 
190
- # Check if renderer is available
191
- if ax.figure.canvas.get_renderer() is None:
192
- ax.figure.canvas.draw()
192
+ # Force renderer to be initialized
193
+ ax.figure.canvas.draw()
193
194
 
194
195
  while (
195
196
  ax.yaxis.get_label()
@@ -211,14 +212,14 @@ def set_fitting_ylabel_fontsize(ax):
211
212
 
212
213
 
213
214
  def add_text(
214
- text,
215
- x="left",
216
- y="top",
217
- fontsize=12,
218
- white_background=False,
219
- ax=None,
215
+ text: str,
216
+ x: float | str = "left",
217
+ y: float | str = "top",
218
+ fontsize: int = 12,
219
+ white_background: bool = False,
220
+ ax: plt.Axes | None = None,
220
221
  **kwargs,
221
- ):
222
+ ) -> None:
222
223
  """
223
224
  Add text to an axis.
224
225
 
@@ -226,9 +227,9 @@ def add_text(
226
227
  ----------
227
228
  text : str
228
229
  The text to add.
229
- x : float, optional
230
+ x : float | str, optional
230
231
  Horizontal position of the text in unit of the normalized x-axis length. The default is value "left", which is an alias for 0.0. Other aliases are "right", "left_in", "right_in", "right_out".
231
- y : float, optional
232
+ y : float | str, optional
232
233
  Vertical position of the text in unit of the normalized y-axis length. The default is value "top", which is an alias for 1.01. Other aliases are "top_in", "bottom_in", "top_out"="top", "bottom_out"="bottom".
233
234
  fontsize : int, optional
234
235
  Font size, by default 12.
@@ -276,14 +277,14 @@ def add_text(
276
277
  }
277
278
 
278
279
  if isinstance(x, str):
279
- x = x_values.get(x)
280
- if x is None:
281
- raise ValueError(f"{x} not a float or a valid position")
280
+ if x not in x_values:
281
+ raise ValueError(f"{x!r} is not a valid x position.")
282
+ x = x_values[x]
282
283
 
283
284
  if isinstance(y, str):
284
- y = y_values.get(y)
285
- if y is None:
286
- raise ValueError(f"{y} not a float or a valid position")
285
+ if y not in y_values:
286
+ raise ValueError(f"{y!r} is not a valid y position.")
287
+ y = y_values[y]
287
288
 
288
289
  t = ax.text(
289
290
  x,
@@ -296,23 +297,23 @@ def add_text(
296
297
 
297
298
  # Add background
298
299
  if white_background:
299
- t.set_bbox(dict(facecolor="white", edgecolor="white"))
300
+ t.set_bbox({"facecolor": "white", "edgecolor": "white"})
300
301
 
301
302
 
302
303
  def add_luminosity(
303
- collaboration,
304
- x="right",
305
- y="top",
306
- fontsize=12,
307
- is_data=True,
308
- lumi="",
309
- lumi_unit="fb",
310
- preliminary=False,
311
- two_lines=False,
312
- white_background=False,
313
- ax=None,
304
+ collaboration: str,
305
+ x: float | str = "right",
306
+ y: float | str = "top",
307
+ fontsize: int = 12,
308
+ is_data: bool = True,
309
+ lumi: int | str = "",
310
+ lumi_unit: str = "fb",
311
+ preliminary: bool = False,
312
+ two_lines: bool = False,
313
+ white_background: bool = False,
314
+ ax: plt.Axes | None = None,
314
315
  **kwargs,
315
- ):
316
+ ) -> None:
316
317
  """
317
318
  Add the collaboration name and the integrated luminosity (or "Simulation").
318
319
 
@@ -320,17 +321,17 @@ def add_luminosity(
320
321
  ----------
321
322
  collaboration : str
322
323
  Collaboration name.
323
- x : float, optional
324
+ x : float | str, optional
324
325
  Horizontal position of the text in unit of the normalized x-axis length. The default is value "right", which is an alias for 1.0. Can take other aliases such as "left", "left_in", "right_in", "right_out".
325
- y : float, optional
326
+ y : float | str, optional
326
327
  Vertical position of the text in unit of the normalized y-axis length. The default is value "top", which is an alias for 1.01. Can take other aliases such as "top_in", "bottom_in", "top_out"="top", "bottom_out"="bottom".
327
328
  fontsize : int, optional
328
329
  Font size, by default 12.
329
330
  is_data : bool, optional
330
331
  If True, plot integrated luminosity. If False, plot "Simulation", by default True.
331
- lumi : int/string, optional
332
+ lumi : int | str, optional
332
333
  Integrated luminosity. If empty, do not plot luminosity. Default value is empty.
333
- lumi_unit : string, optional
334
+ lumi_unit : str, optional
334
335
  Integrated luminosity unit. Default value is fb. The exponent is automatically -1.
335
336
  preliminary : bool, optional
336
337
  If True, print "preliminary", by default False.
@@ -380,7 +381,7 @@ def add_luminosity(
380
381
  )
381
382
 
382
383
 
383
- def plot_reordered_legend(ax, order, **kwargs):
384
+ def plot_reordered_legend(ax: plt.Axes, order: list[int], **kwargs) -> None:
384
385
  """
385
386
  Reorder the legend handlers and labels on the given Matplotlib axis based
386
387
  on the specified order and plot the reordered legend.
@@ -389,7 +390,7 @@ def plot_reordered_legend(ax, order, **kwargs):
389
390
  ----------
390
391
  ax : matplotlib.axes.Axes
391
392
  The Matplotlib Axes object on which the legend is to be reordered.
392
- order : list of int
393
+ order : list[int]
393
394
  A list of integers specifying the new order of the legend items.
394
395
  The integers refer to the indices of the current legend items.
395
396
  kwargs : dict, optional
@@ -415,7 +416,6 @@ def plot_reordered_legend(ax, order, **kwargs):
415
416
  To reorder the legend so that 'Line 2' comes first, use:
416
417
 
417
418
  >>> plot_reordered_legend(ax, [1, 0])
418
-
419
419
  """
420
420
 
421
421
  # Extract the original handlers and labels
@@ -424,8 +424,7 @@ def plot_reordered_legend(ax, order, **kwargs):
424
424
  # Check if order is valid
425
425
  if not all(i in range(len(labels)) for i in order) or len(set(order)) < len(order):
426
426
  raise ValueError(
427
- "The order list should contain all integers from 0 to "
428
- f"{len(labels) - 1}."
427
+ f"The order list should contain all integers from 0 to {len(labels) - 1}."
429
428
  )
430
429
 
431
430
  # Reorder handlers and labels