Skip to content

Commit 2c3b83f

Browse files
committed
feat : implemented broken-axis signed
- add additional space for "show" option, change the tick labels - using slash for "hint", "show" options
1 parent 4208d43 commit 2c3b83f

File tree

1 file changed

+163
-55
lines changed

1 file changed

+163
-55
lines changed

src/mplhep/plot.py

+163-55
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import matplotlib as mpl
88
import matplotlib.pyplot as plt
99
import numpy as np
10-
from matplotlib import patches
1110
from matplotlib.offsetbox import AnchoredText
1211
from matplotlib.transforms import Bbox
1312
from mpl_toolkits.axes_grid1 import axes_size, make_axes_locatable
@@ -182,19 +181,18 @@ def histplot(
182181
plottables = []
183182
final_bins = np.array(
184183
[
185-
final_bins[0] - (final_bins[1] - final_bins[0]) * 2,
184+
final_bins[0] - (final_bins[1] - final_bins[0]) * 3,
185+
final_bins[0] - (final_bins[1] - final_bins[0]),
186186
*final_bins,
187-
final_bins[-1] + (final_bins[1] - final_bins[0]) * 2,
187+
final_bins[-1] + (final_bins[1] - final_bins[0]),
188+
final_bins[-1] + (final_bins[1] - final_bins[0]) * 3,
188189
]
189190
)
190191
for h in hists:
191-
plottables.append(
192-
Plottable(
193-
h.view(flow=True)["value"],
194-
edges=final_bins,
195-
variances=h.view(flow=True)["variance"],
196-
)
197-
)
192+
value, variance = h.view(flow=True)["value"], h.view(flow=True)["variance"]
193+
value, variance = np.insert(value, -1, 0), np.insert(variance, -1, 0)
194+
value, variance = np.insert(value, 1, 0), np.insert(variance, 1, 0)
195+
plottables.append(Plottable(value, edges=final_bins, variances=variance))
198196
# "sum": Add under/overflow bin to first/last bin
199197
elif flow == "sum":
200198
plottables = []
@@ -445,15 +443,89 @@ def iterable_not_string(arg):
445443

446444
if x_axes_label:
447445
ax.set_xlabel(x_axes_label)
448-
if flow == "hint":
446+
if flow == "hint" or flow == "show":
449447
underflow, overflow = 0.0, 0.0
450448
for h in hists:
451449
underflow = underflow + h.view(flow=True)["value"][0]
452450
overflow = overflow + h.view(flow=True)["value"][-1]
451+
d = 0.9 # proportion of vertical to horizontal extent of the slanted line
452+
trans = mpl.transforms.blended_transform_factory(ax.transData, ax.transAxes)
453+
kwargs = dict(
454+
marker=[(-0.5, -d), (0.5, d)],
455+
markersize=15,
456+
linestyle="none",
457+
color="k",
458+
mec="k",
459+
mew=1,
460+
clip_on=False,
461+
transform=trans,
462+
)
463+
xticks = ax.get_xticks().tolist()
453464
if underflow > 0.0:
454-
ax.axvspan(final_bins[0], final_bins[1], facecolor="red", alpha=0.5)
465+
if flow == "hint":
466+
ax.plot(
467+
[
468+
final_bins[0] - (final_bins[1] - final_bins[0]) / 2.0,
469+
final_bins[0],
470+
],
471+
[0, 0],
472+
**kwargs,
473+
)
474+
ax.plot(
475+
[
476+
final_bins[0] - (final_bins[1] - final_bins[0]) / 2.0,
477+
final_bins[0],
478+
],
479+
[1, 1],
480+
**kwargs,
481+
)
482+
if flow == "show":
483+
ax.plot(
484+
[final_bins[1], final_bins[2]],
485+
[0, 0],
486+
**kwargs,
487+
)
488+
ax.plot(
489+
[final_bins[1], final_bins[2]],
490+
[1, 1],
491+
**kwargs,
492+
)
493+
xticks[0] = ""
494+
xticks[1] = f"<{final_bins[2]}"
495+
496+
ax.set_xticklabels(xticks)
455497
if overflow > 0.0:
456-
ax.axvspan(final_bins[-2], final_bins[-1], facecolor="red", alpha=0.5)
498+
if flow == "hint":
499+
ax.plot(
500+
[
501+
final_bins[-1],
502+
final_bins[-1] + (final_bins[1] - final_bins[0]) / 2.0,
503+
],
504+
[0, 0],
505+
**kwargs,
506+
)
507+
ax.plot(
508+
[
509+
final_bins[-1],
510+
final_bins[-1] + (final_bins[1] - final_bins[0]) / 2.0,
511+
],
512+
[1, 1],
513+
**kwargs,
514+
)
515+
if flow == "show":
516+
ax.plot(
517+
[final_bins[-3], final_bins[-2]],
518+
[0, 0],
519+
**kwargs,
520+
)
521+
ax.plot(
522+
[final_bins[-3], final_bins[-2]],
523+
[1, 1],
524+
**kwargs,
525+
)
526+
xticks[-1] = ""
527+
xticks[-2] = f">{final_bins[-3]}"
528+
ax.set_xticklabels(xticks)
457529

458530
return return_artists
459531

@@ -542,18 +614,25 @@ def hist2dplot(
542614
H = hist.view(flow=True)["value"]
543615
xbins = np.array(
544616
[
545-
xbins[0] - (xbins[1] - xbins[0]) * 2,
617+
xbins[0] - (xbins[1] - xbins[0]) * 3,
618+
xbins[0] - (xbins[1] - xbins[0]),
546619
*xbins,
547-
xbins[-1] + (xbins[1] - xbins[0]) * 2,
620+
xbins[-1] + (xbins[1] - xbins[0]),
621+
xbins[-1] + (xbins[1] - xbins[0]) * 3,
548622
]
549623
)
550624
ybins = np.array(
551625
[
552-
ybins[0] - (ybins[1] - ybins[0]) * 2,
626+
ybins[0] - (ybins[1] - ybins[0]) * 3,
627+
ybins[0] - (ybins[1] - ybins[0]),
553628
*ybins,
554-
ybins[-1] + (ybins[1] - ybins[0]) * 2,
629+
ybins[-1] + (ybins[1] - ybins[0]),
630+
ybins[-1] + (ybins[1] - ybins[0]) * 3,
555631
]
556632
)
633+
H = np.insert(H, (1, -1), 0, axis=-1)
634+
H = np.insert(H, (1, -1), np.zeros(np.shape(H)[1]), axis=0)
635+
557636
if flow == "sum":
558637
H[0, 0], H[-1, -1], H[0, -1], H[-1, 0] = (
559638
hist.view(flow=True)["value"][0, 0] + H[0, 0],
@@ -615,48 +694,77 @@ def hist2dplot(
615694
cb_obj = None
616695

617696
plt.sca(ax)
618-
if flow == "hint":
697+
if flow == "hint" or flow == "show":
698+
d = 0.9 # proportion of vertical to horizontal extent of the slanted line
699+
trans = mpl.transforms.blended_transform_factory(ax.transData, ax.transAxes)
700+
kwargs = dict(
701+
marker=[(-0.5, -d), (0.5, d)],
702+
markersize=15,
703+
linestyle="none",
704+
color="k",
705+
mec="k",
706+
mew=1,
707+
clip_on=False,
708+
)
709+
xticks = ax.get_xticks().tolist()
710+
yticks = ax.get_yticks().tolist()
619711
if hist.view(flow=True)["value"][0, 0] > 0.0:
620-
ret1 = patches.Rectangle(
621-
(xbins[0], ybins[0]),
622-
width=xbins[1] - xbins[0],
623-
height=ybins[1] - ybins[0],
624-
fc="none",
625-
ec="r",
626-
lw=2,
627-
)
628-
ax.add_patch(ret1)
629-
712+
if flow == "hint":
713+
ax.plot(
714+
[xbins[0] - (xbins[1] - xbins[0]) / 2.0, xbins[0]],
715+
[0, 0],
716+
transform=trans,
717+
**kwargs,
718+
)
719+
if flow == "show":
720+
ax.plot([xbins[1], xbins[2]], [0, 0], transform=trans, **kwargs)
721+
ax.plot([xbins[0], xbins[0]], [ybins[1], ybins[2]], **kwargs)
722+
xticks[0] = ""
723+
xticks[1] = f"<{xbins[1]}"
724+
ax.set_xticklabels(xticks)
630725
if hist.view(flow=True)["value"][-1, 0] > 0.0:
631-
ret2 = patches.Rectangle(
632-
(xbins[-2], ybins[0]),
633-
width=xbins[1] - xbins[0],
634-
height=ybins[1] - ybins[0],
635-
fc="none",
636-
ec="r",
637-
lw=2,
638-
)
639-
ax.add_patch(ret2)
726+
if flow == "hint":
727+
ax.plot(
728+
[xbins[-1] + (xbins[1] - xbins[0]) / 2.0, xbins[-1]],
729+
[0, 0],
730+
transform=trans,
731+
**kwargs,
732+
)
733+
if flow == "show":
734+
ax.plot([xbins[-3], xbins[-2]], [0, 0], transform=trans, **kwargs)
735+
ax.plot([xbins[-1], xbins[-1]], [ybins[1], ybins[2]], **kwargs)
736+
xticks[-1] = ""
737+
xticks[-2] = f">{xbins[-2]}"
738+
ax.set_xticklabels(xticks)
640739
if hist.view(flow=True)["value"][0, -1] > 0.0:
641-
ret3 = patches.Rectangle(
642-
(xbins[0], ybins[-2]),
643-
width=xbins[1] - xbins[0],
644-
height=ybins[1] - ybins[0],
645-
fc="none",
646-
ec="r",
647-
lw=2,
648-
)
649-
ax.add_patch(ret3)
740+
if flow == "hint":
741+
ax.plot(
742+
[xbins[0], xbins[0] - (xbins[1] - xbins[0]) / 2.0],
743+
[1, 1],
744+
transform=trans,
745+
**kwargs,
746+
)
747+
if flow == "show":
748+
ax.plot([xbins[1], xbins[2]], [1, 1], transform=trans, **kwargs)
749+
ax.plot([xbins[0], xbins[0]], [ybins[-3], ybins[-2]], **kwargs)
750+
yticks[0] = ""
751+
yticks[1] = f"<{ybins[1]}"
752+
ax.set_yticklabels(yticks)
650753
if hist.view(flow=True)["value"][-1, -1] > 0.0:
651-
ret4 = patches.Rectangle(
652-
(xbins[-2], ybins[-2]),
653-
width=xbins[1] - xbins[0],
654-
height=ybins[1] - ybins[0],
655-
fc="none",
656-
ec="r",
657-
lw=2,
658-
)
659-
ax.add_patch(ret4)
754+
if flow == "hint":
755+
ax.plot(
756+
[xbins[-1] + (xbins[1] - xbins[0]) / 2.0, xbins[-1]],
757+
[1, 1],
758+
transform=trans,
759+
**kwargs,
760+
)
761+
if flow == "show":
762+
ax.plot([xbins[-3], xbins[-2]], [1, 1], transform=trans, **kwargs)
763+
ax.plot([xbins[-1], xbins[-1]], [ybins[-3], ybins[-2]], **kwargs)
764+
yticks[-1] = ""
765+
yticks[-2] = f">{ybins[-2]}"
766+
ax.set_yticklabels(yticks)
767+
660768
_labels: np.ndarray | None = None
661769
if isinstance(labels, bool):
662770
_labels = H if labels else None

0 commit comments

Comments
 (0)