plothist 1.5.0__py3-none-any.whl → 1.7.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.
- plothist/__init__.py +8 -11
- plothist/_version.py +16 -3
- plothist/comparison.py +61 -17
- plothist/examples/2d_hist/2d_hist_correlations.py +2 -2
- plothist/examples/utility/uncertainty_types.py +120 -0
- plothist/histogramming.py +8 -2
- plothist/plothist_style.py +2 -2
- plothist/plotters.py +3 -1
- plothist/variable_registry.py +32 -9
- {plothist-1.5.0.dist-info → plothist-1.7.0.dist-info}/METADATA +1 -1
- {plothist-1.5.0.dist-info → plothist-1.7.0.dist-info}/RECORD +14 -13
- plothist-1.7.0.dist-info/licenses/AUTHORS.md +2 -0
- plothist-1.5.0.dist-info/licenses/AUTHORS.md +0 -2
- {plothist-1.5.0.dist-info → plothist-1.7.0.dist-info}/WHEEL +0 -0
- {plothist-1.5.0.dist-info → plothist-1.7.0.dist-info}/licenses/LICENSE +0 -0
plothist/__init__.py
CHANGED
|
@@ -9,12 +9,7 @@ from .comparison import (
|
|
|
9
9
|
get_ratio,
|
|
10
10
|
get_ratio_variances,
|
|
11
11
|
)
|
|
12
|
-
from .histogramming import
|
|
13
|
-
create_axis,
|
|
14
|
-
flatten_2d_hist,
|
|
15
|
-
make_2d_hist,
|
|
16
|
-
make_hist,
|
|
17
|
-
)
|
|
12
|
+
from .histogramming import create_axis, flatten_2d_hist, make_2d_hist, make_hist
|
|
18
13
|
from .plothist_style import (
|
|
19
14
|
add_luminosity,
|
|
20
15
|
add_text,
|
|
@@ -43,6 +38,7 @@ from .variable_registry import (
|
|
|
43
38
|
get_variable_from_registry,
|
|
44
39
|
remove_variable_registry_parameters,
|
|
45
40
|
update_variable_registry,
|
|
41
|
+
update_variable_registry_binning,
|
|
46
42
|
update_variable_registry_ranges,
|
|
47
43
|
)
|
|
48
44
|
|
|
@@ -81,22 +77,24 @@ __all__ = [
|
|
|
81
77
|
"set_fitting_ylabel_fontsize",
|
|
82
78
|
"set_style",
|
|
83
79
|
"update_variable_registry",
|
|
80
|
+
"update_variable_registry_binning",
|
|
84
81
|
"update_variable_registry_ranges",
|
|
85
82
|
]
|
|
86
83
|
|
|
87
84
|
|
|
88
|
-
|
|
85
|
+
from importlib import resources
|
|
89
86
|
from importlib.resources import files
|
|
90
87
|
|
|
88
|
+
import boost_histogram as bh
|
|
89
|
+
import matplotlib.font_manager as fm
|
|
91
90
|
import matplotlib.pyplot as plt
|
|
92
91
|
|
|
92
|
+
# Get style file and use it
|
|
93
|
+
|
|
93
94
|
style_file = files("plothist").joinpath("default_style.mplstyle")
|
|
94
95
|
plt.style.use(style_file)
|
|
95
96
|
|
|
96
97
|
# Install fonts
|
|
97
|
-
from importlib import resources
|
|
98
|
-
|
|
99
|
-
import matplotlib.font_manager as fm
|
|
100
98
|
|
|
101
99
|
with resources.as_file(resources.files("plothist_utils") / "fonts") as font_path:
|
|
102
100
|
font_files = fm.findSystemFonts(fontpaths=[str(font_path)])
|
|
@@ -104,7 +102,6 @@ with resources.as_file(resources.files("plothist_utils") / "fonts") as font_path
|
|
|
104
102
|
fm.fontManager.addfont(font)
|
|
105
103
|
|
|
106
104
|
# Check version of boost_histogram
|
|
107
|
-
import boost_histogram as bh
|
|
108
105
|
|
|
109
106
|
if tuple(int(part) for part in bh.__version__.split(".")) < (1, 4, 0):
|
|
110
107
|
raise ImportError(
|
plothist/_version.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '1.
|
|
21
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.7.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 7, 0)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
plothist/comparison.py
CHANGED
|
@@ -22,9 +22,16 @@ def _check_uncertainty_type(uncertainty_type: str) -> None:
|
|
|
22
22
|
If the uncertainty type is not valid.
|
|
23
23
|
|
|
24
24
|
"""
|
|
25
|
-
|
|
25
|
+
_valid_uncertainty_types = [
|
|
26
|
+
"symmetrical",
|
|
27
|
+
"asymmetrical",
|
|
28
|
+
"asymmetrical_double_sided_zeros",
|
|
29
|
+
"asymmetrical_one_sided_zeros",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
if uncertainty_type not in _valid_uncertainty_types:
|
|
26
33
|
raise ValueError(
|
|
27
|
-
f"Uncertainty type {uncertainty_type} not valid. Must be
|
|
34
|
+
f"Uncertainty type {uncertainty_type} not valid. Must be in {_valid_uncertainty_types}."
|
|
28
35
|
)
|
|
29
36
|
|
|
30
37
|
|
|
@@ -42,11 +49,12 @@ def _is_unweighted(hist: bh.Histogram) -> bool:
|
|
|
42
49
|
bool
|
|
43
50
|
True if the histogram is unweighted, False otherwise.
|
|
44
51
|
"""
|
|
45
|
-
return np.allclose(hist.variances(), hist.values())
|
|
52
|
+
return np.allclose(hist.variances(), hist.values(), equal_nan=True)
|
|
46
53
|
|
|
47
54
|
|
|
48
55
|
def get_asymmetrical_uncertainties(
|
|
49
56
|
hist: bh.Histogram,
|
|
57
|
+
uncertainty_type: str = "asymmetrical",
|
|
50
58
|
) -> tuple[np.ndarray, np.ndarray]:
|
|
51
59
|
"""
|
|
52
60
|
Get Poisson asymmetrical uncertainties for a histogram via a frequentist approach based on a confidence-interval computation.
|
|
@@ -57,6 +65,8 @@ def get_asymmetrical_uncertainties(
|
|
|
57
65
|
----------
|
|
58
66
|
hist : bh.Histogram
|
|
59
67
|
The histogram.
|
|
68
|
+
uncertainty_type : str, optional
|
|
69
|
+
The type of uncertainty to compute for bins with 0 entry. Default is "asymmetrical" (= "asymmetrical_one_sided_zeros"). Use "asymmetrical_double_sided_zeros" to have the double-sided definition. More information in :ref:`documentation-statistics-label`.
|
|
60
70
|
|
|
61
71
|
Returns
|
|
62
72
|
-------
|
|
@@ -72,16 +82,44 @@ def get_asymmetrical_uncertainties(
|
|
|
72
82
|
|
|
73
83
|
"""
|
|
74
84
|
_check_counting_histogram(hist)
|
|
85
|
+
_check_uncertainty_type(uncertainty_type)
|
|
75
86
|
|
|
76
87
|
if not _is_unweighted(hist):
|
|
77
88
|
raise ValueError(
|
|
78
89
|
"Asymmetrical uncertainties can only be computed for an unweighted histogram."
|
|
79
90
|
)
|
|
80
|
-
|
|
81
|
-
alpha = 1.0 -
|
|
91
|
+
|
|
92
|
+
alpha = 1.0 - 0.682689492
|
|
93
|
+
tail_probability = alpha / 2
|
|
94
|
+
|
|
82
95
|
n = hist.values()
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
|
|
97
|
+
lower_bound = np.zeros_like(n, dtype=float)
|
|
98
|
+
upper_bound = np.zeros_like(n, dtype=float)
|
|
99
|
+
|
|
100
|
+
# Two-sided Garwood intervals for n > 0
|
|
101
|
+
lower_bound[n > 0] = stats.gamma.ppf(q=tail_probability, a=n[n > 0], scale=1)
|
|
102
|
+
upper_bound[n > 0] = stats.gamma.ppf(
|
|
103
|
+
q=1 - tail_probability, a=n[n > 0] + 1, scale=1
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
if uncertainty_type == "asymmetrical_double_sided_zeros":
|
|
107
|
+
# Two-sided Garwood intervals for n == 0
|
|
108
|
+
upper_bound[n == 0] = stats.gamma.ppf(q=1 - tail_probability, a=1, scale=1)
|
|
109
|
+
elif uncertainty_type in ["asymmetrical_one_sided_zeros", "asymmetrical"]:
|
|
110
|
+
# One-sided upper limit for n == 0
|
|
111
|
+
upper_bound[n == 0] = stats.gamma.ppf(q=1 - 2 * tail_probability, a=1, scale=1)
|
|
112
|
+
else:
|
|
113
|
+
raise ValueError(
|
|
114
|
+
f"Invalid uncertainty type '{uncertainty_type}' for asymmetrical uncertainties."
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Compute asymmetric uncertainties
|
|
118
|
+
uncertainties_low = n - lower_bound
|
|
119
|
+
uncertainties_high = upper_bound - n
|
|
120
|
+
|
|
121
|
+
uncertainties_low = np.nan_to_num(uncertainties_low, nan=0.0)
|
|
122
|
+
uncertainties_high = np.nan_to_num(uncertainties_high, nan=0.0)
|
|
85
123
|
|
|
86
124
|
return uncertainties_low, uncertainties_high
|
|
87
125
|
|
|
@@ -174,8 +212,10 @@ def get_pull(
|
|
|
174
212
|
_check_counting_histogram(h1)
|
|
175
213
|
_check_counting_histogram(h2)
|
|
176
214
|
|
|
177
|
-
if
|
|
178
|
-
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
215
|
+
if "asymmetrical" in h1_uncertainty_type:
|
|
216
|
+
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
217
|
+
h1, h1_uncertainty_type
|
|
218
|
+
)
|
|
179
219
|
h1_variances = np.where(
|
|
180
220
|
h1.values() >= h2.values(),
|
|
181
221
|
uncertainties_low**2,
|
|
@@ -232,8 +272,10 @@ def get_difference(
|
|
|
232
272
|
|
|
233
273
|
difference_values = h1.values() - h2.values()
|
|
234
274
|
|
|
235
|
-
if
|
|
236
|
-
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
275
|
+
if "asymmetrical" in h1_uncertainty_type:
|
|
276
|
+
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
277
|
+
h1, h1_uncertainty_type
|
|
278
|
+
)
|
|
237
279
|
|
|
238
280
|
difference_uncertainties_low = np.sqrt(uncertainties_low**2 + h2.variances())
|
|
239
281
|
difference_uncertainties_high = np.sqrt(uncertainties_high**2 + h2.variances())
|
|
@@ -390,11 +432,13 @@ def get_ratio(
|
|
|
390
432
|
|
|
391
433
|
ratio_values = np.where(h2.values() != 0, h1.values() / h2.values(), np.nan)
|
|
392
434
|
|
|
393
|
-
if
|
|
394
|
-
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
435
|
+
if "asymmetrical" in h1_uncertainty_type:
|
|
436
|
+
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
437
|
+
h1, h1_uncertainty_type
|
|
438
|
+
)
|
|
395
439
|
|
|
396
440
|
if ratio_uncertainty_type == "uncorrelated":
|
|
397
|
-
if
|
|
441
|
+
if "asymmetrical" in h1_uncertainty_type:
|
|
398
442
|
h1_high = h1.copy()
|
|
399
443
|
h1_high[:] = np.c_[h1_high.values(), uncertainties_high**2]
|
|
400
444
|
h1_low = h1.copy()
|
|
@@ -405,7 +449,7 @@ def get_ratio(
|
|
|
405
449
|
ratio_uncertainties_low = np.sqrt(get_ratio_variances(h1, h2))
|
|
406
450
|
ratio_uncertainties_high = ratio_uncertainties_low
|
|
407
451
|
elif ratio_uncertainty_type == "split":
|
|
408
|
-
if
|
|
452
|
+
if "asymmetrical" in h1_uncertainty_type:
|
|
409
453
|
ratio_uncertainties_low = uncertainties_low / h2.values()
|
|
410
454
|
ratio_uncertainties_high = uncertainties_high / h2.values()
|
|
411
455
|
else:
|
|
@@ -493,7 +537,7 @@ def get_comparison(
|
|
|
493
537
|
h1, h2, h1_uncertainty_type
|
|
494
538
|
)
|
|
495
539
|
elif comparison == "asymmetry":
|
|
496
|
-
if
|
|
540
|
+
if "asymmetrical" in h1_uncertainty_type:
|
|
497
541
|
raise ValueError(
|
|
498
542
|
"Asymmetrical uncertainties are not supported for the asymmetry comparison."
|
|
499
543
|
)
|
|
@@ -501,7 +545,7 @@ def get_comparison(
|
|
|
501
545
|
lower_uncertainties = uncertainties
|
|
502
546
|
upper_uncertainties = uncertainties
|
|
503
547
|
elif comparison == "efficiency":
|
|
504
|
-
if
|
|
548
|
+
if "asymmetrical" in h1_uncertainty_type:
|
|
505
549
|
raise ValueError(
|
|
506
550
|
"Asymmetrical uncertainties are not supported in an efficiency computation."
|
|
507
551
|
)
|
|
@@ -20,7 +20,7 @@ from plothist import (
|
|
|
20
20
|
get_variable_from_registry,
|
|
21
21
|
make_2d_hist,
|
|
22
22
|
plot_2d_hist,
|
|
23
|
-
|
|
23
|
+
update_variable_registry_binning,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
# No need to redo this step if the registry was already created before
|
|
@@ -28,7 +28,7 @@ variable_keys = ["variable_0", "variable_1", "variable_2"]
|
|
|
28
28
|
unique_id = str(int(time.time() * 1000))[-8:] # unique ID based on current time
|
|
29
29
|
temporary_registry_path = f"./_temporary_variable_registry_{unique_id}.yaml"
|
|
30
30
|
create_variable_registry(variable_keys, path=temporary_registry_path)
|
|
31
|
-
|
|
31
|
+
update_variable_registry_binning(df, variable_keys, path=temporary_registry_path)
|
|
32
32
|
|
|
33
33
|
# Get all the correlation plot between the variables
|
|
34
34
|
variable_keys_combinations = list(combinations(variable_keys, 2))
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Representation of different uncertainty types.
|
|
3
|
+
==============================================
|
|
4
|
+
|
|
5
|
+
This example demonstrates how to use the `plot_error_hist` function with different uncertainty types
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import boost_histogram as bh
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
from plothist import add_text, plot_error_hist
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def shifted_array(values, offset: int, size: int = 15) -> np.ndarray:
|
|
16
|
+
"""
|
|
17
|
+
Create an array of a given size with NaNs and fill it with values at specified offsets.
|
|
18
|
+
The values are inserted at every offset starting from the given offset.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
arr = np.full(size, np.nan)
|
|
22
|
+
indices = range(offset, size, len(values))
|
|
23
|
+
|
|
24
|
+
for i, idx in enumerate(indices):
|
|
25
|
+
if i >= len(values):
|
|
26
|
+
break
|
|
27
|
+
arr[idx] = values[i]
|
|
28
|
+
|
|
29
|
+
return arr
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def make_grouped_edges(
|
|
33
|
+
n_groups, group_size=4, inner_spacing=0.1, inter_spacing=0.2
|
|
34
|
+
) -> np.ndarray:
|
|
35
|
+
"""
|
|
36
|
+
Create a set of edges for a histogram with grouped categories.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
edges = [
|
|
40
|
+
group_start + i * inner_spacing
|
|
41
|
+
for group in range(n_groups)
|
|
42
|
+
for i in range(group_size)
|
|
43
|
+
for group_start in [
|
|
44
|
+
group * (group_size * inner_spacing + inter_spacing - inner_spacing)
|
|
45
|
+
]
|
|
46
|
+
]
|
|
47
|
+
return np.array(edges)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Create a category axis with explicit locations
|
|
51
|
+
edges = make_grouped_edges(4)
|
|
52
|
+
axis = bh.axis.Variable(edges)
|
|
53
|
+
|
|
54
|
+
hists = []
|
|
55
|
+
entries = [0, 0.5, 3, 500]
|
|
56
|
+
|
|
57
|
+
for k in range(3):
|
|
58
|
+
hist = bh.Histogram(axis, storage=bh.storage.Weight())
|
|
59
|
+
values = shifted_array(entries, k)
|
|
60
|
+
hist[:] = np.c_[values, values]
|
|
61
|
+
hists.append(hist)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
fig, (ax_top, ax_bot) = plt.subplots(
|
|
65
|
+
2, 1, gridspec_kw={"height_ratios": [1, 3], "hspace": 0.05}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
for ax in (ax_top, ax_bot):
|
|
69
|
+
plot_error_hist(
|
|
70
|
+
hists[0], ax=ax, label="symmetrical", uncertainty_type="symmetrical"
|
|
71
|
+
)
|
|
72
|
+
plot_error_hist(
|
|
73
|
+
hists[1], ax=ax, label="asymmetrical", uncertainty_type="asymmetrical"
|
|
74
|
+
)
|
|
75
|
+
plot_error_hist(
|
|
76
|
+
hists[2],
|
|
77
|
+
ax=ax,
|
|
78
|
+
label="asymmetrical_double_sided_zeros",
|
|
79
|
+
uncertainty_type="asymmetrical_double_sided_zeros",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
add_text("plot_error_hist() with different uncertainty type", ax=ax_top, x="right")
|
|
83
|
+
|
|
84
|
+
# Set axis limits
|
|
85
|
+
ax_top.set_ylim(465, 530)
|
|
86
|
+
ax_bot.set_ylim(-0.5, 6.9)
|
|
87
|
+
ax_bot.set_xlim(xmin=-0.05)
|
|
88
|
+
|
|
89
|
+
# Format bottom ticks and labels
|
|
90
|
+
ax_bot.set_xticks(edges[1::4] + 0.05)
|
|
91
|
+
ax_bot.set_xlabel("Entry category")
|
|
92
|
+
ax_bot.set_xticklabels(entries)
|
|
93
|
+
ax_bot.set_ylabel("Entries")
|
|
94
|
+
ax_bot.yaxis.label.set_horizontalalignment("left")
|
|
95
|
+
ax_bot.spines.top.set_visible(False)
|
|
96
|
+
ax_bot.xaxis.set_minor_locator(plt.NullLocator()) # Hide x-axis minor ticks
|
|
97
|
+
|
|
98
|
+
# Format top ticks and labels
|
|
99
|
+
ax_top.xaxis.tick_top()
|
|
100
|
+
ax_top.spines.bottom.set_visible(False)
|
|
101
|
+
ax_top.set_xticklabels([])
|
|
102
|
+
ax_top.set_xticks([])
|
|
103
|
+
|
|
104
|
+
# Draw break marks
|
|
105
|
+
d = 0.5 # proportion of vertical to horizontal extent of the slanted line
|
|
106
|
+
kwargs = {
|
|
107
|
+
"marker": [(-1, -d), (1, d)],
|
|
108
|
+
"markersize": 12,
|
|
109
|
+
"linestyle": "none",
|
|
110
|
+
"color": "k",
|
|
111
|
+
"mec": "k",
|
|
112
|
+
"mew": 1,
|
|
113
|
+
"clip_on": False,
|
|
114
|
+
}
|
|
115
|
+
ax_top.plot([0, 1], [0, 0], transform=ax_top.transAxes, **kwargs)
|
|
116
|
+
ax_bot.plot([0, 1], [1, 1], transform=ax_bot.transAxes, **kwargs)
|
|
117
|
+
|
|
118
|
+
ax_top.legend(loc="upper left")
|
|
119
|
+
|
|
120
|
+
fig.savefig("uncertainty_types.svg", bbox_inches="tight")
|
plothist/histogramming.py
CHANGED
|
@@ -109,6 +109,7 @@ def make_hist(
|
|
|
109
109
|
bins: int | list[float] | np.ndarray = 50,
|
|
110
110
|
range: tuple[float | str, float | str] | None = None,
|
|
111
111
|
weights: float | list[float] | np.ndarray = 1,
|
|
112
|
+
mute_warning: bool = False,
|
|
112
113
|
) -> bh.Histogram:
|
|
113
114
|
"""
|
|
114
115
|
Create a histogram object and fill it with the provided data.
|
|
@@ -129,6 +130,8 @@ def make_hist(
|
|
|
129
130
|
Weight(s) to apply to the data points (default is 1).
|
|
130
131
|
If a float, a single weight is applied to all data points.
|
|
131
132
|
If an array-like, weights are applied element-wise.
|
|
133
|
+
mute_warning : bool, optional
|
|
134
|
+
Whether to mute warnings about data outside the binning range (default is False).
|
|
132
135
|
|
|
133
136
|
Returns
|
|
134
137
|
-------
|
|
@@ -160,7 +163,7 @@ def make_hist(
|
|
|
160
163
|
range_coverage = h.sum().value / n_data
|
|
161
164
|
|
|
162
165
|
# Issue a warning if more than 1% of the data is outside of the binning range
|
|
163
|
-
if range_coverage < 0.99:
|
|
166
|
+
if range_coverage < 0.99 and not mute_warning:
|
|
164
167
|
warnings.warn(
|
|
165
168
|
f"Only {100 * range_coverage:.2f}% of data contained in the binning range [{axis.edges[0]}, {axis.edges[-1]}].",
|
|
166
169
|
category=RangeWarning,
|
|
@@ -177,6 +180,7 @@ def make_2d_hist(
|
|
|
177
180
|
tuple[float | str, float | str] | None, tuple[float | str, float | str] | None
|
|
178
181
|
] = (None, None),
|
|
179
182
|
weights: float | list[float] | np.ndarray = 1,
|
|
183
|
+
mute_warning: bool = False,
|
|
180
184
|
) -> bh.Histogram:
|
|
181
185
|
"""
|
|
182
186
|
Create a 2D histogram object and fill it with the provided data.
|
|
@@ -198,6 +202,8 @@ def make_2d_hist(
|
|
|
198
202
|
Weight(s) to apply to the data points (default is 1).
|
|
199
203
|
If a float, a single weight is applied to all data points.
|
|
200
204
|
If an array-like, weights are applied element-wise.
|
|
205
|
+
mute_warning : bool, optional
|
|
206
|
+
Whether to mute warnings about data outside the binning range (default is False).
|
|
201
207
|
|
|
202
208
|
Returns
|
|
203
209
|
-------
|
|
@@ -245,7 +251,7 @@ def make_2d_hist(
|
|
|
245
251
|
range_coverage = h.sum().value / n_data
|
|
246
252
|
|
|
247
253
|
# Issue a warning if more than 1% of the data is outside of the binning range
|
|
248
|
-
if range_coverage < 0.99:
|
|
254
|
+
if range_coverage < 0.99 and not mute_warning:
|
|
249
255
|
warnings.warn(
|
|
250
256
|
f"Only {100 * range_coverage:.2f}% of data contained in the binning range ([{x_axis.edges[0]}, {x_axis.edges[-1]}], [{y_axis.edges[0]}, {y_axis.edges[-1]}]).",
|
|
251
257
|
category=RangeWarning,
|
plothist/plothist_style.py
CHANGED
|
@@ -112,7 +112,7 @@ def cubehelix_palette(
|
|
|
112
112
|
pal = cmap(x)[:, :3].tolist()
|
|
113
113
|
if reverse:
|
|
114
114
|
pal = pal[::-1]
|
|
115
|
-
return pal
|
|
115
|
+
return [tuple(c) for c in pal]
|
|
116
116
|
|
|
117
117
|
|
|
118
118
|
def get_color_palette(
|
|
@@ -170,7 +170,7 @@ def get_color_palette(
|
|
|
170
170
|
)
|
|
171
171
|
|
|
172
172
|
plt_cmap = plt.get_cmap(cmap)
|
|
173
|
-
return plt_cmap(np.linspace(0, 1, N))
|
|
173
|
+
return [tuple(k) for k in plt_cmap(np.linspace(0, 1, N))]
|
|
174
174
|
|
|
175
175
|
|
|
176
176
|
def set_fitting_ylabel_fontsize(ax: plt.Axes) -> float:
|
plothist/plotters.py
CHANGED
|
@@ -406,7 +406,9 @@ def plot_error_hist(
|
|
|
406
406
|
if uncertainty_type == "symmetrical":
|
|
407
407
|
kwargs.setdefault("yerr", np.sqrt(hist.variances()))
|
|
408
408
|
else:
|
|
409
|
-
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
409
|
+
uncertainties_low, uncertainties_high = get_asymmetrical_uncertainties(
|
|
410
|
+
hist, uncertainty_type
|
|
411
|
+
)
|
|
410
412
|
kwargs.setdefault("yerr", [uncertainties_low, uncertainties_high])
|
|
411
413
|
|
|
412
414
|
kwargs.setdefault("fmt", ".")
|
plothist/variable_registry.py
CHANGED
|
@@ -8,6 +8,7 @@ import os
|
|
|
8
8
|
import warnings
|
|
9
9
|
|
|
10
10
|
import boost_histogram as bh
|
|
11
|
+
import numpy as np
|
|
11
12
|
import yaml
|
|
12
13
|
|
|
13
14
|
from plothist.histogramming import create_axis
|
|
@@ -126,7 +127,7 @@ def create_variable_registry(
|
|
|
126
127
|
{
|
|
127
128
|
variable_key: {
|
|
128
129
|
"name": variable_key,
|
|
129
|
-
"bins":
|
|
130
|
+
"bins": "auto",
|
|
130
131
|
"range": ("min", "max"),
|
|
131
132
|
"label": variable_key,
|
|
132
133
|
"log": False,
|
|
@@ -259,25 +260,37 @@ def remove_variable_registry_parameters(
|
|
|
259
260
|
_save_variable_registry(variable_registry, path=path)
|
|
260
261
|
|
|
261
262
|
|
|
262
|
-
def update_variable_registry_ranges(
|
|
263
|
+
def update_variable_registry_ranges(*args, **kwargs):
|
|
264
|
+
warnings.warn(
|
|
265
|
+
"`update_variable_registry_ranges` is deprecated since v1.7.0 and will be removed in future versions. "
|
|
266
|
+
"Use `update_variable_registry_binning` instead.",
|
|
267
|
+
DeprecationWarning,
|
|
268
|
+
stacklevel=2,
|
|
269
|
+
)
|
|
270
|
+
return update_variable_registry_binning(*args, **kwargs)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def update_variable_registry_binning(
|
|
263
274
|
data,
|
|
264
275
|
variable_keys: list[str] | None = None,
|
|
265
276
|
path: str = "./variable_registry.yaml",
|
|
266
277
|
overwrite: bool = False,
|
|
267
278
|
) -> None:
|
|
268
279
|
"""
|
|
269
|
-
Update the range parameters for multiple variables in the variable registry file.
|
|
280
|
+
Update both the bins and range parameters for multiple variables in the variable registry file.
|
|
270
281
|
|
|
271
282
|
Parameters
|
|
272
283
|
----------
|
|
273
284
|
data : numpy.ndarray or pandas.DataFrame
|
|
274
285
|
A dataset containing the data for the variables.
|
|
275
286
|
variable_keys : list[str]
|
|
276
|
-
A list of variable keys for which to update the
|
|
287
|
+
A list of variable keys for which to update the parameters in the registry.
|
|
288
|
+
The variable needs to have a bin and range properties in the registry.
|
|
289
|
+
Default is None: all variables in the registry are updated.
|
|
277
290
|
path : str, optional
|
|
278
291
|
The path to the variable registry file (default is "./variable_registry.yaml").
|
|
279
292
|
overwrite : bool, optional
|
|
280
|
-
If True, the range parameters will be overwritten even if
|
|
293
|
+
If True, the bin and range parameters will be overwritten even if they differ from "auto" and ("min", "max") (default is False).
|
|
281
294
|
|
|
282
295
|
Returns
|
|
283
296
|
-------
|
|
@@ -302,13 +315,23 @@ def update_variable_registry_ranges(
|
|
|
302
315
|
f"Variable {variable_key} does not have a name, bins or range property in the registry {path}."
|
|
303
316
|
)
|
|
304
317
|
|
|
305
|
-
|
|
318
|
+
bins = "auto" if overwrite else variable["bins"]
|
|
319
|
+
bin_number = len(np.histogram_bin_edges(data[variable["name"]], bins=bins)) - 1
|
|
306
320
|
|
|
307
|
-
|
|
308
|
-
|
|
321
|
+
range_val = ("min", "max") if overwrite else variable["range"]
|
|
322
|
+
|
|
323
|
+
if bins == "auto" or tuple(range_val) == ("min", "max"):
|
|
324
|
+
axis = create_axis(
|
|
325
|
+
bin_number,
|
|
326
|
+
tuple(range_val),
|
|
327
|
+
data[variable["name"]],
|
|
328
|
+
)
|
|
309
329
|
if isinstance(axis, bh.axis.Regular):
|
|
310
330
|
update_variable_registry(
|
|
311
|
-
{
|
|
331
|
+
{
|
|
332
|
+
"bins": bin_number,
|
|
333
|
+
"range": (float(axis.edges[0]), float(axis.edges[-1])),
|
|
334
|
+
},
|
|
312
335
|
[variable_key],
|
|
313
336
|
path=path,
|
|
314
337
|
overwrite=True,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
plothist/__init__.py,sha256
|
|
2
|
-
plothist/_version.py,sha256=
|
|
1
|
+
plothist/__init__.py,sha256=-cUpXXg2cCdfjcbYAQWHLUHq-5kLsxSWgEbgtZYjqBA,2817
|
|
2
|
+
plothist/_version.py,sha256=oGRWiKvEGHesjf5wCNHGVlYfAA3dInDJeL5EiMaru6A,704
|
|
3
3
|
plothist/_version.pyi,sha256=o7uNL6MhuJoiqpEnriU7rBT6TmkJZA-i2qMoNz9YcgQ,82
|
|
4
|
-
plothist/comparison.py,sha256=
|
|
4
|
+
plothist/comparison.py,sha256=jkONOiCp8RNBk8V_VvwACdfJJqo89rK9NQW71XxJscc,19623
|
|
5
5
|
plothist/default_style.mplstyle,sha256=7MmB2uiXmD_DSqFHeH1xxC-lTctBD_EASxMdSOsPep0,1574
|
|
6
|
-
plothist/histogramming.py,sha256=
|
|
7
|
-
plothist/plothist_style.py,sha256=
|
|
8
|
-
plothist/plotters.py,sha256=
|
|
6
|
+
plothist/histogramming.py,sha256=Q0KRQjdyZGXj7J-qlXgzUbb-s7duqZG4QD2BIuVNQes,11828
|
|
7
|
+
plothist/plothist_style.py,sha256=bbYFc-qsrTfdbacCBAAzmiHJoRIh3toBomFfxtTRNMs,13255
|
|
8
|
+
plothist/plotters.py,sha256=ncPZa34Fo1mbFxv0guFc2zEciX_JXGKJxeIfcUDaP6w,46336
|
|
9
9
|
plothist/test_helpers.py,sha256=JXhxUdqMszkawxkU8cDPqipkSXNHfsKSfe3K-4frDrM,1379
|
|
10
|
-
plothist/variable_registry.py,sha256=
|
|
10
|
+
plothist/variable_registry.py,sha256=lYQ1DxUXBtY_UlZcuvwf_XQllq5MdPFKBmIrnRTNauo,11536
|
|
11
11
|
plothist/examples/README.rst,sha256=PVzkOQzVnNeWORxEv3NNv5XoSN2Y71D7SYzRkCqirfA,151
|
|
12
12
|
plothist/examples/1d_hist/1d_comparison_asymmetry.py,sha256=Rp9gv6E5z9KgIhnraS9AjGSMgHLhSHd_u5L-vG0w-gU,757
|
|
13
13
|
plothist/examples/1d_hist/1d_comparison_difference.py,sha256=FMKoTjMIQp6VsFXspVBy2AdxHPDnxhMfj9PCvE4qVjk,877
|
|
@@ -26,7 +26,7 @@ plothist/examples/1d_hist/1d_profile.py,sha256=otmerm64DNAYnRWaablQkQDgUVOvjLNDc
|
|
|
26
26
|
plothist/examples/1d_hist/1d_side_by_side.py,sha256=sAHhBVnopINQscFaUpVI4KNs18e_1laHyrYBOlmU_fQ,1557
|
|
27
27
|
plothist/examples/1d_hist/1d_str_category.py,sha256=2DtxfNMAlcZ6pYx44lP0-sgY4M73-R0aBH61uEJmKA0,880
|
|
28
28
|
plothist/examples/1d_hist/README.rst,sha256=GT4-w9W-TDtjOqibOPcd6vYzAGO8bDsgxBRp3fD1uTw,100
|
|
29
|
-
plothist/examples/2d_hist/2d_hist_correlations.py,sha256=
|
|
29
|
+
plothist/examples/2d_hist/2d_hist_correlations.py,sha256=c9PMymxNn9Kz0STvDQ3Pro4ndv-1PVG5RZsJCS9gobA,1836
|
|
30
30
|
plothist/examples/2d_hist/2d_hist_simple.py,sha256=1n5yqOJxHzD31njOk85dTjuXhkogCDIS4-EG63XcnQ0,521
|
|
31
31
|
plothist/examples/2d_hist/2d_hist_simple_discrete_colormap.py,sha256=E1zeMIDP25R_ppkB-wDz7TxaLsxf7dCs87FrPTPWTAc,1000
|
|
32
32
|
plothist/examples/2d_hist/2d_hist_uneven.py,sha256=kR53XrSx38efG1wHEI69BIcPKVQzJygkr7ax_CFzBIA,646
|
|
@@ -56,8 +56,9 @@ plothist/examples/utility/add_text_example.py,sha256=EB7ZUStt2E8GawjWNmVbSV34NIN
|
|
|
56
56
|
plothist/examples/utility/color_palette_hists.py,sha256=uIc6TrmjTj8EUif1Yj1wq4nXoY1sgJpS15yPe3-FpTw,2383
|
|
57
57
|
plothist/examples/utility/color_palette_squares.py,sha256=pNasgvZZApu-sCqhi5FTJAH3l6Px2cgB5RwJcQ1eF1U,2689
|
|
58
58
|
plothist/examples/utility/matplotlib_vs_plothist_style.py,sha256=iEIfbFKmAN-PcDCzw_sBuhrfpes4I2wUVfC0r1vUHEw,2006
|
|
59
|
-
plothist
|
|
60
|
-
plothist-1.
|
|
61
|
-
plothist-1.
|
|
62
|
-
plothist-1.
|
|
63
|
-
plothist-1.
|
|
59
|
+
plothist/examples/utility/uncertainty_types.py,sha256=r1yxzEvxn5Clv0ZIok9JjVh3RB-YQ_usWhFnpvl1els,3259
|
|
60
|
+
plothist-1.7.0.dist-info/METADATA,sha256=X_mWIcy0jZbKaLcNPGaoL2jR4y1RnBYcnpQw-FgqlqM,4737
|
|
61
|
+
plothist-1.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
62
|
+
plothist-1.7.0.dist-info/licenses/AUTHORS.md,sha256=-2hRQyzJdkGgYPu8J-xDAWCwiqomcR56uYuzlJ4yMJM,115
|
|
63
|
+
plothist-1.7.0.dist-info/licenses/LICENSE,sha256=bfaEdGehofQDaw-zDdVMHNUKo1FrOm6oGUEF-ltrp6w,1523
|
|
64
|
+
plothist-1.7.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|