Skip to content

Commit 19a91e0

Browse files
docs: add utility functions (#631)
* feat: fix and use mh.subplots in examples * docs: added utilities * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * docs: added mh.model tips * docs: added add_text plots * docs: tweak description of mh.hist --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 271a858 commit 19a91e0

14 files changed

+233
-64
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ new_docs/docs/guide_advanced.md
1313
new_docs/docs/guide_comparisons.md
1414
new_docs/docs/guide_styling.md
1515
new_docs/docs/guide_basic_plotting.md
16+
new_docs/docs/guide_utilities.md
1617

1718
# Byte-compiled / optimized / DLL files
1819
__pycache__/

examples/model_ex/model_all_comparisons.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
# --8<-- [start:full_code]
99
# --8<-- [start:imports]
1010
import hist
11-
import matplotlib.pyplot as plt
1211
import numpy as np
1312
import seaborn as sns
1413

@@ -44,15 +43,7 @@
4443
# --8<-- [end:setup]
4544

4645
# --8<-- [start:plot_body]
47-
fig, axes = plt.subplots(
48-
nrows=6, figsize=(6, 13), gridspec_kw={"height_ratios": [3, 1, 1, 1, 1, 1]}
49-
)
50-
fig.subplots_adjust(hspace=0.3)
51-
52-
# Hide x-axis labels for all but the bottom plot
53-
for ax in axes[:-1]:
54-
ax.xaxis.set_ticklabels([])
55-
ax.set_xlabel(" ")
46+
fig, axes = mh.subplots(nrows=6, hspace=0.3)
5647

5748
mh.comp.data_model(
5849
data_hist=data_hist,

examples/model_ex/model_all_comparisons_no_model_unc.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
# --8<-- [start:full_code]
99
# --8<-- [start:imports]
1010
import hist
11-
import matplotlib.pyplot as plt
1211
import numpy as np
1312
import seaborn as sns
1413

@@ -71,15 +70,8 @@
7170

7271
# --8<-- [start:plot_body]
7372
# Create comparison plots
74-
fig, axes = plt.subplots(
75-
nrows=6,
76-
figsize=(6, 13),
77-
gridspec_kw={"height_ratios": [3, 1, 1, 1, 1, 1]},
78-
)
79-
fig.subplots_adjust(hspace=0.3)
80-
for ax in axes[:-1]:
81-
ax.xaxis.set_ticklabels([])
82-
ax.set_xlabel(" ")
73+
fig, axes = mh.subplots(nrows=6, hspace=0.3)
74+
8375
background_sum = sum(background_hists)
8476

8577
mh.comp.data_model(

new_docs/docs/guide.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Welcome to the mplhep user guide! This documentation is organized into focused s
1414
```
1515

1616
### [**Histogram Plotting**](guide_basic_plotting.md)
17-
Functions for 1D and 2D pre-binned histograms with support for the [Unified Histogram Interface (UHI)](https://uhi.readthedocs.io/)
17+
Functions for 1D and 2D pre-binned histograms with support for the [Unified Histogram Interface (UHI)](https://uhi.readthedocs.io/).
1818

1919
- [1D Histogram Plotting](guide_basic_plotting.md#1d-histogram-plotting)
2020
- [Supported Input Formats](guide_basic_plotting.md#supported-input-formats)
@@ -33,16 +33,26 @@ High-level functions for data-model comparisons.
3333
- [Additional examples](guide_comparisons.md#additional-examples)
3434

3535
### [**Styling**](guide_styling.md)
36-
Official styles for ATLAS, CMS, LHCb, ALICE, and DUNE experiments
36+
Official styles for ATLAS, CMS, LHCb, ALICE, and DUNE experiments.
3737

3838
- [Setting experiment styles](guide_styling.md#setting-experiment-styles)
3939
- [Setting experiment labels](guide_styling.md#setting-experiment-labels)
4040
- [Configuring experiment labels](guide_styling.md#configuring-experiment-labels)
4141

42-
### [**To go further**](guide_advanced.md)
43-
Utility functions, experiment-specific label formatters, UHI integration, and best practices
42+
### [**Utilities**](guide_utilities.md)
43+
Utility functions and experiment-specific label formatters.
4444

4545
- [Text placement](guide_advanced.md#text-placement)
46+
- [Subplot creation](guide_utilities.md#subplot-creation)
47+
- [Save variations](guide_utilities.md#save-variations)
48+
- [Fit y-label](guide_utilities.md#fit-y-label)
49+
- [mpl_magic](guide_utilities.md#mpl_magic)
50+
- [Axes manipulation](guide_utilities.md#axes-manipulation)
51+
- [plt.hist wrapper](guide_utilities.md#hist-wrapper)
52+
53+
### [**To go further**](guide_advanced.md)
54+
UHI integration and best practices.
55+
4656
- [Working with UHI Histograms](guide_advanced.md#working-with-uhi-histograms)
4757
- [Best practices](guide_advanced.md#best-practices)
4858

new_docs/docs/guide_advanced_template.md

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Advanced Features
1+
# To go further
22

33
This section covers advanced mplhep features and utilities..
44

@@ -13,18 +13,6 @@ This section covers advanced mplhep features and utilities..
1313
# mh.style.use('<as appropriate>')
1414
```
1515

16-
## Text placement
17-
18-
For custom text placement:
19-
20-
```python
21-
# Add text at specific location
22-
txt = mh.add_text('Custom Text', loc='upper right')
23-
24-
# Append additional text
25-
mh.append_text('Additional info', txt, loc='below')
26-
```
27-
2816
## Working with UHI Histograms
2917

3018
mplhep fully supports the [Unified Histogram Interface](https://uhi.readthedocs.io/), making it compatible with modern histogram libraries:

new_docs/docs/guide_comparisons_template.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,9 @@ To compare data to a model made of multiple components (e.g. signal, backgrounds
462462

463463
{{TABS_END}}
464464

465+
!!! tip
466+
To only plot the model, without data or comparison panel, use [`mh.model()`][mplhep.plot.model]. It takes the same arguments as [`mh.comp.data_model()`][mplhep.comp.data_model], except for the `data_hist` and `comparison` parameters.
467+
465468
#### Showcasing more options
466469

467470
[`mh.comp.data_model()`][mplhep.comp.data_model] is very flexible and can be customized further. For more examples and details, see the [API Reference](api.md#mplhep.comp.data_model) and the [Gallery](gallery.md). Here is a selection of additional examples showcasing some of the available options.
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Utilities
2+
3+
This section covers advanced mplhep features and utilities.
4+
5+
??? tip "Prerequisites"
6+
Throughout this guide the following codeblock is assumed.
7+
```python
8+
import matplotlib.pyplot as plt
9+
import numpy as np
10+
import hist
11+
np.random.seed(42)
12+
import mplhep as mh
13+
# mh.style.use('<as appropriate>')
14+
```
15+
16+
## Text placement
17+
18+
### Add text
19+
20+
[mh.add_text][mplhep.add_text] will add text to a specified location on the axis. It has flexible positioning options, that are accessible via the `loc` argument, or the `x` and `y` arguments.
21+
22+
{{TABS_START}}
23+
{{TAB_HEADER}}
24+
25+
=== "loc argument"
26+
27+
```python
28+
# mkdocs: render
29+
# mkdocs: align=left
30+
import matplotlib.pyplot as plt # mkdocs: hide
31+
import mplhep as mh # mkdocs: hide
32+
{{STYLE_USE_CODE}} # mkdocs: hide
33+
fig, ax = plt.subplots()
34+
35+
locs = [
36+
"upper left", # or "top left"
37+
"upper right", # or "top right"
38+
"lower left", # or "bottom left"
39+
"lower right", # or "bottom right"
40+
"over left",
41+
"over right",
42+
"under left",
43+
"under right",
44+
]
45+
46+
for loc in locs:
47+
mh.add_text(
48+
f'Text with\nloc="{loc}"',
49+
loc=loc,
50+
ax=ax,
51+
)
52+
```
53+
54+
=== "x and y arguments"
55+
56+
```python
57+
# mkdocs: render
58+
# mkdocs: align=left
59+
import matplotlib.pyplot as plt # mkdocs: hide
60+
import mplhep as mh # mkdocs: hide
61+
{{STYLE_USE_CODE}} # mkdocs: hide
62+
fig, ax = plt.subplots()
63+
64+
positions = [
65+
("right_in", "top_in"),
66+
("left_in", "top_in"),
67+
("left_in", "bottom_in"),
68+
("right_in", "bottom_in"),
69+
("right", "top_out"),
70+
("left", "top_out"),
71+
("right_out", "top_in"),
72+
("right_out", "bottom_in"),
73+
("right", "bottom_out"),
74+
("left", "bottom_out"),
75+
]
76+
77+
for x, y in positions:
78+
mh.add_text(
79+
f'Text with\nx="{x}"\ny="{y}"',
80+
x=x,
81+
y=y,
82+
ax=ax,
83+
)
84+
```
85+
86+
{{TABS_END}}
87+
88+
### Append text
89+
90+
[mh.append_text][mplhep.append_text] appends additional text relative to an existing text object created with [mh.add_text][mplhep.add_text]. The new text can be positioned above, below, left, or right of the existing text.
91+
92+
```python
93+
# Add text at specific location
94+
txt = mh.add_text('Custom Text', loc='upper right')
95+
96+
# Append additional text
97+
mh.append_text('Additional info', txt, loc='below')
98+
```
99+
100+
## Subplot creation
101+
102+
[mh.subplots][mplhep.subplots] is a wrapper around `plt.subplots` to create a figure with multiple subplots. It conveniently adjusts the figure size and spacing between subplots if multiple rows are requested.
103+
104+
```python
105+
fig, axes = mh.subplots(nrows=6)
106+
# Will scale the figure, and add spacing between rows and remove the xlabels on inner plots.
107+
```
108+
109+
## Save variations
110+
111+
[mh.savelabels][mplhep.savelabels] automatically generates multiple versions of a plot with different experiment label text variations, useful for creating preliminary and final versions of plots.
112+
113+
```python
114+
mh.savelabels('test.png')
115+
# Produces: test.png, test_pas.png, test_supp.png, test_wip.png, with no label, 'Preliminary', 'Supplementary', and 'Work in Progress' labels respectively.
116+
117+
mh.savelabels('test', labels=[("FOO", "foo.pdf"), ("BAR", "bar")])
118+
# Produces: foo.pdf, test_bar.png
119+
```
120+
121+
## Fit y-label
122+
123+
[mh.set_fitting_ylabel_fontsize][mplhep.set_fitting_ylabel_fontsize] adjusts the y-axis label font size to fit within the figure when there are long y-axis labels.
124+
125+
```python
126+
mh.set_fitting_ylabel_fontsize(ax)
127+
```
128+
129+
## mpl_magic
130+
131+
The function [mh.mpl_magic][mplhep.mpl_magic] applies several common mplhep utilities to a given axis:
132+
133+
- [mh.set_ylow][mplhep.set_ylow]: Sets a minimum y-axis limit based on data.
134+
- [mh.yscale_legend][mplhep.yscale_legend]: Rescales the y-axis to fit the legend.
135+
- [mh.yscale_anchored_text][mplhep.yscale_anchored_text]: Rescales the y-axis to fit anchored text.
136+
137+
```python
138+
mh.mpl_magic(ax)
139+
```
140+
141+
You can also call these functions individually as needed.
142+
143+
## Axes manipulation
144+
145+
### Add colorbar axis
146+
147+
[mh.make_square_add_cbar][mplhep.make_square_add_cbar] creates a square axis and adds a colorbar axis to the right, useful for 2D histograms.
148+
149+
```python
150+
ax_colorbar = mh.make_square_add_cbar(ax)
151+
# ax is now square, and ax_colorbar is the colorbar axis.
152+
```
153+
154+
### Add axis
155+
156+
[mh.append_axes][mplhep.append_axes] appends a new axis to an existing axis in a specified direction (top, bottom, left, right).
157+
158+
```python
159+
ax_new = mh.append_axes(ax, position='top', size=2, pad=0.3)
160+
# Adds a new axis above ax with height 2 inches and 0.3 inch padding.
161+
```
162+
163+
## plt.hist wrapper
164+
165+
[mh.hist][mplhep.hist] is a drop-in replacement for [mh.histplot][mplhep.histplot] which runs the `np.histogram` function before plotting. It provides a convenient way to create a histogram of raw data values and benefits from the extended features of [mh.histplot][mplhep.histplot], such as automatic error bar calculation, bin-width normalization and HEP-style plotting options.
166+
167+
!!! warning
168+
[mh.hist][mplhep.hist] does not return a histogram object compatible with the Unified Histogram Interface (UHI), thus cannot be used directly with other mplhep histogram plotting functions.
169+
170+
```python
171+
data = np.random.normal(100, 15, 1000)
172+
mh.hist(data, bins=50, range=(50, 150))
173+
174+
# Multiple datasets
175+
data1 = np.random.normal(100, 15, 1000)
176+
data2 = np.random.normal(120, 15, 1000)
177+
mh.hist([data1, data2], bins=50, label=['Dataset 1', 'Dataset 2'])
178+
```

new_docs/generate_style_guides.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ def main():
282282
"guide_comparisons_template.md": "guide_comparisons.md",
283283
"guide_styling_template.md": "guide_styling.md",
284284
"guide_advanced_template.md": "guide_advanced.md",
285+
"guide_utilities_template.md": "guide_utilities.md",
285286
}
286287

287288
# Process each template

new_docs/mkdocs.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ exclude_docs: |
156156
guide_basic_plotting_template.md
157157
guide_comparisons_template.md
158158
guide_styling_template.md
159+
guide_utilities_template.md
159160
guide_advanced_template.md
160161
161162
nav:
@@ -165,7 +166,8 @@ nav:
165166
- Basic Plotting: guide_basic_plotting.md
166167
- Comparisons: guide_comparisons.md
167168
- Styling: guide_styling.md
168-
- Utilities: guide_advanced.md
169+
- Utilities: guide_utilities.md
170+
- To go further: guide_advanced.md
169171
- Gallery:
170172
- Overview: gallery.md
171173
- 1D Comparisons:

src/mplhep/plot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,15 @@ def hist(
148148
149149
Examples
150150
--------
151-
>>> import mplhep as hep
151+
>>> import mplhep as mh
152152
>>> import numpy as np
153153
>>> data = np.random.normal(100, 15, 1000)
154-
>>> hep.hist(data, bins=50, range=(50, 150))
154+
>>> mh.hist(data, bins=50, range=(50, 150))
155155
156156
>>> # Multiple datasets
157157
>>> data1 = np.random.normal(100, 15, 1000)
158158
>>> data2 = np.random.normal(120, 15, 1000)
159-
>>> hep.hist([data1, data2], bins=50, label=['Dataset 1', 'Dataset 2'])
159+
>>> mh.hist([data1, data2], bins=50, label=['Dataset 1', 'Dataset 2'])
160160
161161
See Also
162162
--------

0 commit comments

Comments
 (0)