Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make hist more flexible #1150

Merged
merged 5 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/src/plotting_functions/hist.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,17 @@ hist(data, normalization = :pdf, bar_labels = :values,
label_formatter=x-> round(x, digits=2), label_size = 15,
strokewidth = 0.5, strokecolor = (:black, 0.5), color = :values)
```

#### Moving histograms

With `scale_to`, and `offset`, one can put multiple histograms into the same plot.
Note, that offset automatically sets fillto, to move the whole barplot.
Also, one can use a negative `scale_to` amount to flip the histogram.
```@example hist
fig = Figure()
ax = Axis(fig[1, 1])
for i in 1:5
hist!(ax, randn(1000), scale_to=-0.6, offset=i, direction=:x)
end
fig
```
13 changes: 9 additions & 4 deletions src/basic_recipes/barplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ $(ATTRIBUTES)
@recipe(BarPlot, x, y) do scene
Attributes(;
fillto = automatic,
offset = 0.0,
color = theme(scene, :patchcolor),
colormap = theme(scene, :colormap),
colorrange = automatic,
Expand Down Expand Up @@ -180,7 +181,7 @@ function Makie.plot!(p::BarPlot)
label_aligns = Observable(Vec2f0[])
label_offsets = Observable(Vec2f0[])
label_colors = Observable(RGBAf0[])
function calculate_bars(xy, fillto, width, dodge, n_dodge, x_gap, dodge_gap, stack,
function calculate_bars(xy, fillto, offset, width, dodge, n_dodge, x_gap, dodge_gap, stack,
dir, bar_labels, flip_labels_at, label_color, color_over_background,
color_over_bar, label_formatter, label_offset)

Expand Down Expand Up @@ -208,10 +209,14 @@ function Makie.plot!(p::BarPlot)

if stack === automatic
if fillto === automatic
fillto = 0.0
fillto = offset
end
elseif eltype(stack) <: Integer
fillto === automatic || @warn "Ignore keyword fillto when keyword stack is provided"
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
if !iszero(offset)
@warn "Ignore keyword offset when keyword stack is provided"
offset = 0.0
end
i_stack = stack

from, to = stack_grouped_from_to(i_stack, y, (x = x̂,))
Expand All @@ -233,10 +238,10 @@ function Makie.plot!(p::BarPlot)
labels[], label_aligns[], label_offsets[], label_colors[] = label_args
end

return bar_rectangle.(x̂, y, barwidth, fillto, in_y_direction)
return bar_rectangle.(x̂, y .+ offset, barwidth, fillto, in_y_direction)
end

bars = lift(calculate_bars, p[1], p.fillto, p.width, p.dodge, p.n_dodge, p.x_gap,
bars = lift(calculate_bars, p[1], p.fillto, p.offset, p.width, p.dodge, p.n_dodge, p.x_gap,
p.dodge_gap, p.stack, p.direction, p.bar_labels, p.flip_labels_at,
p.label_color, p.color_over_background, p.color_over_bar, p.label_formatter, p.label_offset)

Expand Down
19 changes: 16 additions & 3 deletions src/stats/hist.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ can be normalized by setting `normalization`. Possible values are:
norm 1.
* `:none`: Do not normalize.

The following attributes can move the histogram around,
which comes in handy when placing multiple histograms into one plot:
* offset = 0.0: adds an offset to every value
* fillto = 0.0: defines where the bar starts
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
* scale_to = nothing: allows to scale all values to a certain height
* flip = false: flips all values

Color can either be:
* a vector of `bins` colors
* a single color
Expand All @@ -42,6 +49,9 @@ $(ATTRIBUTES)
normalization = :none,
cycle = [:color => :patchcolor],
color = theme(scene, :patchcolor),
offset = 0.0,
fillto = automatic,
scale_to = nothing,

bar_labels = nothing,
flip_labels_at = Inf,
Expand Down Expand Up @@ -72,14 +82,17 @@ function Makie.plot!(plot::Hist)
end
end

points = lift(edges, plot.normalization) do edges, normalization
points = lift(edges, plot.normalization, plot.scale_to) do edges, normalization, scale_to
h = StatsBase.fit(StatsBase.Histogram, values[], edges)
h_norm = StatsBase.normalize(h, mode = normalization)
centers = edges[1:end-1] .+ (diff(edges) ./ 2)
weights = h_norm.weights
if !isnothing(scale_to)
max = maximum(weights)
weights .= weights ./ max .* scale_to
end
return Point2f0.(centers, weights)
end

widths = lift(diff, edges)
color = lift(plot.color) do color
if color === :values
Expand All @@ -93,7 +106,7 @@ function Makie.plot!(plot::Hist)
x === :values ? :y : x
end
# plot the values, not the observables, to be in control of updating
bp = barplot!(plot, points[]; width = widths[], plot.attributes..., bar_labels=bar_labels, color=color)
bp = barplot!(plot, points[]; width = widths[], plot.attributes..., fillto=plot.fillto, offset=plot.offset, bar_labels=bar_labels, color=color)

# update the barplot points without triggering, then trigger with `width`
on(widths) do w
Expand Down