-
Notifications
You must be signed in to change notification settings - Fork 29
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
Add plotting via Makie as Extension #454
base: master
Are you sure you want to change the base?
Changes from 4 commits
0d29296
39ee2cf
8b1fb82
20e76a4
38f7b44
b5847c5
1144212
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
module MCMCChainsMakieExt | ||
|
||
import MCMCChains | ||
import Makie | ||
|
||
|
||
function MCMCChains.trace(chns::T) where {T<:MCMCChains.Chains} | ||
params = MCMCChains.names(chns, :parameters) | ||
|
||
n_chains = length(MCMCChains.chains(chns)) | ||
n_samples = length(chns) | ||
n_params = length(params) | ||
|
||
colors = Makie.to_colormap(:tol_vibrant) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As @devmotion this is a bit too opiniated, what if I want to use a different set of colors? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will explore ways to make more flexible. |
||
width = 600 | ||
height = max(400, 80 * n_params) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for this, it is too restrictive... |
||
|
||
fig = Makie.Figure(; size=(width, height)) | ||
|
||
for (i, param) in enumerate(params) | ||
ax = Makie.Axis(fig[i+1, 1]; ylabel=string(param)) | ||
for chain in 1:n_chains | ||
values = chns[:, param, chain] | ||
Makie.lines!( | ||
ax, | ||
1:n_samples, | ||
values; | ||
label=string(chain), | ||
color=(colors[chain], 0.7), | ||
linewidth=0.7 | ||
) | ||
end | ||
|
||
Makie.hideydecorations!(ax; label=false) | ||
if i < n_params | ||
Makie.hidexdecorations!(ax; grid=false) | ||
else | ||
ax.xlabel = "Iteration" | ||
end | ||
end | ||
|
||
for (i, param) in enumerate(params) | ||
ax = Makie.Axis(fig[i+1, 2]; ylabel=string(param)) | ||
for chain in 1:n_chains | ||
values = chns[:, param, chain] | ||
Makie.density!( | ||
ax, | ||
values; | ||
label=string(chain), | ||
color=(colors[chain], 0.1), | ||
strokewidth=1, | ||
strokecolor=(colors[chain], 0.7) | ||
) | ||
end | ||
|
||
Makie.hideydecorations!(ax) | ||
if i < n_params | ||
Makie.hidexdecorations!(ax; grid=false) | ||
else | ||
ax.xlabel = "Parameter estimate" | ||
end | ||
end | ||
|
||
axes = [only(Makie.contents(fig[i+1, 2])) for i in 1:n_params] | ||
Makie.linkxaxes!(axes...) | ||
|
||
Makie.Legend(fig[1, 1:2], first(axes), "Chain", orientation=:horizontal, titlehalign=:left, halign=:left, titleposition=:left) | ||
|
||
Makie.rowgap!(fig.layout, 10) | ||
Makie.colgap!(fig.layout, 10) | ||
|
||
return fig | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think
trace
is an appropriate name, it should be something liketraceplot
orplot_chains
to make it clear this is outputting a figure.If you decide to go the method dispatch way, it would be good to deconstruct it a bit better:
Axis
This way the code is beneficial for anyone who would just like some part of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trace
follows the convention that plot names in the Julia ecosystem don't have theplot
postfix, e.g.scatter
orlines
instead ofscatterplot
orlinesplot
Recipes are for creating a single sub-plot, not defining a figure with multiple sub-plots. I'm not sure there's a way to use a recipe unless all chains and parameters were plotted into a single sub-plot and not faceted the way MCMC plots tend to be
Edit: I think I understand the desire for this, but I think this goes back to the fact that MCMC-type plots are facets of multiple plots/axes instead. MCMC-type plots are inherently figures not just axes/plots So, e.g.
trace!(axis,...)
isn't feasible with the facets.i.e. where you could get the left side and right sight separately?