Created
January 11, 2021 14:22
-
-
Save jkrumbiegel/5baa32d0c010cb842e037603a18663cd to your computer and use it in GitHub Desktop.
Histstep recipe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@recipe(Histstep, values) do scene | |
Attributes( | |
bins = 15, # Int or iterable of edges | |
normalization = :none | |
) | |
end | |
function AbstractPlotting.plot!(plot::Histstep) | |
values = plot[:values] | |
edges = lift(values, plot.bins) do vals, bins | |
if bins isa Int | |
mi, ma = float.(extrema(vals)) | |
ma = nextfloat(ma) # hist is right-open, so to include the upper data point, make the last bin a tiny bit bigger | |
return range(mi, ma, length = bins+1) | |
else | |
if !issorted(bins) | |
error("Histogram bins are not sorted: $bins") | |
end | |
return bins | |
end | |
end | |
points = lift(edges, plot.normalization) do edges, normalization | |
h = AbstractPlotting.StatsBase.fit(AbstractPlotting.StatsBase.Histogram, values[], edges) | |
h_norm = AbstractPlotting.StatsBase.normalize(h, mode = normalization) | |
weights = h_norm.weights | |
ps = Vector{Point2f0}(undef, 2 * (length(edges) - 1)) | |
for (i, (e1, e2, w)) in enumerate(zip(edges[1:end-1], edges[2:end], weights)) | |
ps[i*2-1] = Point2f0(e1, w) | |
ps[i*2] = Point2f0(e2, w) | |
end | |
return ps | |
end | |
widths = lift(diff, edges) | |
# plot the values, not the observables, to be in control of updating | |
bp = lines!(plot, points[]; width = widths[], plot.attributes...) | |
# update the barplot points without triggering, then trigger with `width` | |
on(widths) do w | |
setindex!(bp[1], points[], notify = _ -> false) | |
bp.width = w | |
end | |
plot | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment