diff --git a/src/mplhep/plot.py b/src/mplhep/plot.py index e10497cd..51d046b3 100644 --- a/src/mplhep/plot.py +++ b/src/mplhep/plot.py @@ -4,10 +4,10 @@ from collections import OrderedDict, namedtuple from typing import TYPE_CHECKING, Any, Union +import hist as Hist import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np -import hist as Hist from matplotlib.offsetbox import AnchoredText from matplotlib.transforms import Bbox from mpl_toolkits.axes_grid1 import axes_size, make_axes_locatable @@ -132,7 +132,7 @@ def histplot( Attempts to draw x-axis ticks coinciding with bin boundaries if feasible. ax : matplotlib.axes.Axes, optional Axes object (if None, last one is fetched or one is created) - flow : str, optional {None, "show", "sum", "hint"} + flow : str, optional { "show", "sum", "hint"} Whether plot the under/overflow bin. If "show", add additional under/overflow bin. If "sum", add the under/overflow bin content to first/last bin. **kwargs : Keyword arguments passed to underlying matplotlib functions - @@ -597,7 +597,7 @@ def hist2dplot( Colorbar maximum. ax : matplotlib.axes.Axes, optional Axes object (if None, last one is fetched or one is created) - flow : str, optional {None, "show", "sum","hint"} + flow : str, optional {"show", "sum","hint"} Whether plot the under/overflow bin. If "show", add additional under/overflow bin. If "sum", add the under/overflow bin content to first/last bin. "hint" would highlight the bins with under/overflow contents **kwargs : Keyword arguments passed to underlying matplotlib function - pcolormesh. diff --git a/tests/baseline/test_histplot_flow.png b/tests/baseline/test_histplot_flow.png index a72f83fc..493fa857 100644 Binary files a/tests/baseline/test_histplot_flow.png and b/tests/baseline/test_histplot_flow.png differ diff --git a/tests/baseline/test_histplot_hist_flow.png b/tests/baseline/test_histplot_hist_flow.png new file mode 100644 index 00000000..3dd6d3ca Binary files /dev/null and b/tests/baseline/test_histplot_hist_flow.png differ diff --git a/tests/baseline/test_histplot_type_flow.png b/tests/baseline/test_histplot_type_flow.png new file mode 100644 index 00000000..d6b3535d Binary files /dev/null and b/tests/baseline/test_histplot_type_flow.png differ diff --git a/tests/baseline/test_histplot_uproot_flow.png b/tests/baseline/test_histplot_uproot_flow.png new file mode 100644 index 00000000..36155c30 Binary files /dev/null and b/tests/baseline/test_histplot_uproot_flow.png differ diff --git a/tests/test_basic.py b/tests/test_basic.py index 35129fc8..5e11857b 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -115,37 +115,110 @@ def test_histplot_density(): def test_histplot_flow(): np.random.seed(0) h = hist.Hist(hist.axis.Regular(20, 5, 15, name="x"), hist.storage.Weight()) + h.fill(np.random.normal(10, 3, 400)) + fig, axs = plt.subplots(1, 3, sharey=True, figsize=(15, 5)) + axs = axs.flatten() + hep.histplot(h, ax=axs[0], flow="hint") + hep.histplot(h, ax=axs[1], flow="show") + hep.histplot(h, ax=axs[2], flow="sum") + + axs[0].set_title("Default(hint)", fontsize=18) + axs[1].set_title("Show", fontsize=18) + axs[2].set_title("Sum", fontsize=18) + return fig + + +@pytest.mark.mpl_image_compare(style="default") +def test_histplot_hist_flow(): + np.random.seed(0) + entries = np.random.normal(10, 3, 400) + h = hist.Hist(hist.axis.Regular(20, 5, 15, name="x"), hist.storage.Weight()) h2 = hist.Hist(hist.axis.Regular(20, 5, 15, name="x"), hist.storage.Weight()) h3 = hist.Hist(hist.axis.Regular(20, 5, 15, name="x"), hist.storage.Weight()) - - one_side = np.random.normal(10, 3, 400) - one_side = one_side[one_side > 5] - no_flow = np.random.normal(10, 3, 400) - no_flow = no_flow[(no_flow < 15) & (no_flow > 5)] - h.fill(np.random.normal(10, 3, 400)) - h2.fill(one_side) - h3.fill(no_flow) - fig, axs = plt.subplots(1, 3, sharey=True, figsize=(15, 5)) + h4 = hist.Hist(hist.axis.Regular(20, 5, 15, name="x"), hist.storage.Weight()) + + h.fill(entries) + h2.fill(entries[entries < 15]) + h3.fill(entries[entries > 5]) + h4.fill(entries[(entries > 5) & (entries < 15)]) + import uproot + + f = uproot.recreate("flow_th1.root") + f["h"] = h + f["h2"] = h2 + f["h3"] = h3 + f["h4"] = h4 + fig, axs = plt.subplots(2, 2, sharey=True, figsize=(10, 10)) axs = axs.flatten() - hep.histplot(h3, ax=axs[2], flow="hint") + + hep.histplot(h, ax=axs[0], flow="show") + hep.histplot(h2, ax=axs[1], flow="show") hep.histplot(h3, ax=axs[2], flow="show") - hep.histplot(h3, ax=axs[2], flow="sum") - hep.histplot(h2, ax=axs[1], flow="hint") + hep.histplot(h4, ax=axs[3], flow="show") + + axs[0].set_title("Two-side overflow", fontsize=18) + axs[1].set_title("Left-side overflow", fontsize=18) + axs[2].set_title("Right-side overflow", fontsize=18) + axs[3].set_title("No overflow", fontsize=18) + fig.subplots_adjust(hspace=0.2, wspace=0.2) + axs[0].legend() + return fig + + +@pytest.mark.mpl_image_compare(style="default") +def test_histplot_uproot_flow(): + np.random.seed(0) + entries = np.random.normal(10, 3, 400) + import uproot + + f = uproot.open("flow_th1.root") + h = f["h"] + h2 = f["h2"] + h3 = f["h3"] + h4 = f["h4"] + + fig, axs = plt.subplots(2, 2, sharey=True, figsize=(10, 10)) + axs = axs.flatten() + + hep.histplot(h, ax=axs[0], flow="show") hep.histplot(h2, ax=axs[1], flow="show") - hep.histplot(h2, ax=axs[1], flow="sum") - hep.histplot(h, ax=axs[0], flow="hint", label="hint") - hep.histplot(h, ax=axs[0], flow="show", label="show") - hep.histplot(h, ax=axs[0], flow="sum", label="sum") + hep.histplot(h3, ax=axs[2], flow="show") + hep.histplot(h4, ax=axs[3], flow="show") axs[0].set_title("Two-side overflow", fontsize=18) - axs[1].set_title("One-side overflow", fontsize=18) - axs[2].set_title("No overflow", fontsize=18) - fig.subplots_adjust(hspace=0.1, wspace=0.1) + axs[1].set_title("Left-side overflow", fontsize=18) + axs[2].set_title("Right-side overflow", fontsize=18) + axs[3].set_title("No overflow", fontsize=18) + fig.subplots_adjust(hspace=0.2, wspace=0.2) axs[0].legend() return fig +@pytest.mark.mpl_image_compare(style="default") +def test_histplot_type_flow(): + np.random.seed(0) + entries = np.random.normal(10, 3, 400) + + histh = hist.Hist( + hist.axis.Regular(20, 5, 15, name="x", flow=False), hist.storage.Weight() + ) + nph, bins = np.histogram(entries, bins=20, range=(5, 15)) + histh.fill(entries) + + fig, axs = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(10, 5)) + axs = axs.flatten() + + hep.histplot(histh, ax=axs[0], flow="hint") + hep.histplot(nph, bins, ax=axs[1], flow="hint") + + axs[0].set_title("hist, noflow bin", fontsize=18) + axs[1].set_title("numpy hist", fontsize=18) + # axs[0].set_xlim(0,20) + # axs[1].set_xlim(0,20) + return fig + + @pytest.mark.mpl_image_compare(style="default", remove_text=True) def test_histplot_multiple(): np.random.seed(0)