Skip to content

Instantly share code, notes, and snippets.

@jkrumbiegel
Created January 11, 2021 14:22
Show Gist options
  • Save jkrumbiegel/5baa32d0c010cb842e037603a18663cd to your computer and use it in GitHub Desktop.
Save jkrumbiegel/5baa32d0c010cb842e037603a18663cd to your computer and use it in GitHub Desktop.
Histstep recipe
@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