It is currently trivially simple to plot the posterior likelihood functions from a MCMC chain with StatsPlots. However, it was quite easy to make a function that allows the same automatic plotting with Makie:
Setup
julia> using Turing
julia> @model function normalmodel(y)
# Our prior belief about the probability
μ ~ Uniform(extrema(y)...)
σ ~ Uniform(0, 10^3) # σ must be positive
# The number of observations.
N = length(y)
# Each sample is distributed as Normal(μ, σ)
y .~ filldist(Normal(μ, σ), N)
end
julia> N_samples = 20;
julia> N_MCMC = 10^3;
julia> μ_true = 15;
julia> σ_true = 1;
julia> data_normal = rand(Normal(μ_true, σ_true), N_samples);
julia> normal_instance = normalmodel(data_normal);
julia> Threads.nthreads()
4
julia> chain_normal = sample(normal_instance, NUTS(), MCMCThreads(), N_MCMC, 4);
Ploting function definition
julia> using GLMakie
julia> import Makie.plot
julia> function Makie.plot(ch::Chains)
fig = Figure()
for (ind, param) in enumerate(ch.name_map.parameters)
ax = Axis(fig[ind, 1], title=string(param))
for (ind2, datavec) in enumerate(eachcol(getindex(ch, param).data))
# Get current default colorpalette
colors = Makie.current_default_theme().attributes[:palette][][:color][]
density!(ax, datavec, color=(:black, 0.0),
strokearound=true,
strokewidth=2,
strokecolor=colors[ind2%length(colors)]
)
end
end
display(fig)
return fig
end
I would say something like this is better off in a glue package. For base Makie I don’t think the convenience for the people who want this would be worth the inconvenience of extra dependencies, compile and using time for all.
This stuff actually works pretty well with AlgebraOfGraphics, one just needs to transform the chains into appropriate table objects. They are already tables but not quite in the right format
It indeed did until a few days ago. Then it started to complain about a colormap if compiled with GLMakie. I wish there was something like fillcolor=:none in Makie’s density().
FWIW, there’s more than one way to convert MCMC draws to a table. MCMCChains.Chains takes an approach that mirrors how Chains itself flattens multidimensional outputs. ArviZ.jl, which can consume Chains objects, takes a different approach. Both implement the Tables interface and can be used with StatsPlots.jl and AlgebraOfGraphics.jl, but which approach is best for you may vary from plot to plot.
Could someone provide example code of how to transform the samples into a table in a format consumable by AlgebraOfGraphics? Ideally a MWE like the one I provided, but using AlgebraOfGraphics
using AlgebraOfGraphics, GLMakie
using AlgebraOfGraphics: density
fig = Figure()
for (i, var_name) in enumerate((:μ, :σ))
draw!(
fig[i, 1],
data(chain_normal) *
mapping(var_name; color=:chain => nonnumeric) *
density() *
visual(fillalpha=0)
)
end
The main difference from the plot in the OP is that AlgebraOfGraphics uses the variable name as the x-axis label instead of the title, which is sensible since that’s what the ticks correspond to.
We need to loop over the variable names in this case because they’re found in different columns.