Integration with MCMCChains.jl
MCMC packages like Turing often produce results in the form of an MCMCChains.Chain. There is special support in PairPlots.jl for plotting these chains.
Note
The integration between PairPlots and MCMCChains only works on Julia 1.9 and above. On previous versions, you can work around this by running pairplot(DataFrame(chn))
.
Plotting chains
For this example, we'll use the following code to generate a Chain
. In a real code, you would likely receive a chain as a result of sampling from a model.
chn1 = Chains(randn(10000, 5, 3) .* [1 2 3 4 5] .* [1;;;2;;;3], [:a, :b, :c, :d, :e])
Chains MCMC chain (10000×5×3 Array{Float64, 3}):
Iterations = 1:1:10000
Number of chains = 3
Samples per chain = 10000
parameters = a, b, c, d, e
Summary Statistics
parameters mean std mcse ess_bulk ess_tail rhat ⋯
Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯
a -0.0187 2.1514 0.0123 30302.2767 1161.6288 1.1283 ⋯
b -0.0244 4.3161 0.0248 30208.2463 1208.5271 1.1281 ⋯
c 0.0413 6.5381 0.0390 28410.2835 1151.4747 1.1324 ⋯
d 0.0098 8.6366 0.0496 30302.0166 1199.0290 1.1334 ⋯
e 0.1107 10.8906 0.0629 30114.2514 1245.8560 1.1303 ⋯
1 column omitted
Quantiles
parameters 2.5% 25.0% 50.0% 75.0% 97.5%
Symbol Float64 Float64 Float64 Float64 Float64
a -4.6094 -1.1762 -0.0080 1.1483 4.4746
b -9.2585 -2.3415 -0.0303 2.3172 9.1260
c -13.9140 -3.4532 0.0078 3.5461 13.8935
d -18.1072 -4.6024 -0.0080 4.6961 18.3996
e -22.9666 -5.7514 0.1001 5.9582 23.1356
You can plot the results from all chains in the Chains object:
using CairoMakie, PairPlots
pairplot(chn1)
The labels are taken from the column names of the chains. You can modify them by passing in a dictionary mapping column names to strings, LaTeX strings, or Makie rich text objects.
Plotting individual chains separately
If you have multiple parallel chains and want to plot them in different colors, you can pass each one to pairplot
:
pairplot(chn1[:,:,1], chn1[:,:,2], chn1[:,:,3])
You can title the series indepdendently as well:
c1 = Makie.wong_colors(0.5)[1]
c2 = Makie.wong_colors(0.5)[2]
c3 = Makie.wong_colors(0.5)[3]
pairplot(
PairPlots.Series(chn1[:,:,1], label="chain 1", color=c1, strokecolor=c1),
PairPlots.Series(chn1[:,:,2], label="chain 2", color=c2, strokecolor=c2),
PairPlots.Series(chn1[:,:,3], label="chain 3", color=c3, strokecolor=c3),
)
If your chains are well converged, then the different series should look the same.
Comparing the results of two simulations
You may want to compare the results of two simulations. Consider the following chains:
chn2 = Chains(randn(10000, 5, 1) .* [1 2 3 4 5], [:a, :b, :c, :d, :e])
chn3 = Chains(randn(10000, 4, 1) .* [5 4 2 1], [:a, :b, :d, :e]);
Chains MCMC chain (10000×4×1 Array{Float64, 3}):
Iterations = 1:1:10000
Number of chains = 1
Samples per chain = 10000
parameters = a, b, d, e
Summary Statistics
parameters mean std mcse ess_bulk ess_tail rhat ⋯
Symbol Float64 Float64 Float64 Float64 Float64 Float64 ⋯
a 0.0459 5.0209 0.0508 9775.8402 9484.1439 1.0000 ⋯
b -0.0495 4.0080 0.0404 9831.4933 9129.9240 1.0000 ⋯
d -0.0231 2.0015 0.0203 9722.5839 9635.3466 1.0001 ⋯
e -0.0096 0.9985 0.0098 10272.4670 10005.3430 1.0002 ⋯
1 column omitted
Quantiles
parameters 2.5% 25.0% 50.0% 75.0% 97.5%
Symbol Float64 Float64 Float64 Float64 Float64
a -9.6441 -3.3700 0.0169 3.4159 9.9293
b -7.8490 -2.7882 -0.0902 2.6991 7.7831
d -3.8987 -1.3695 -0.0466 1.3218 3.9356
e -1.9530 -0.6973 -0.0150 0.6775 1.9487
Just pass them all to pairplot
:
pairplot(chn2, chn3)
Note how the parameters of the chains do not have to match exactly. Here, chn2
has an additional variable not present in chn3
.