# Failing to plot correlograms in Julia: Makie vs. AoG vs StatsPlots

**URL:** <https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971>\
**Category:** New to Julia\
**Tags:** plotting, statsplots, makie, algebraofgraphics\
**Created:** [December 23, 2023, 12:42pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971 "2023-12-23T12:42:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 23, 2023, 12:42pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/1 "2023-12-23T12:42:22Z")

</div>

I am trying with any possible package to plot a classic correlation plot (scatterplots for each variable vs each other and density histogram on the diagonal in the middle). Sometime they are cold correlogram or pairplots. I come from R and Python and it is dead easy with each language to get a plot in no time.

These have been my attempts so far:

**Statsplots corrplot** `@df df corrplot(cols(1:11), grid = false, fc=:thermal)`  
I was happy to see a macro for this. Works OK but makes **julia crash and hang unresponsively** with \> 11 columns (issue reported on Statsplots with reproducible example: I use the Boston housing dataset).  
I tried converting the df to a Matrix but the plot still crashes (at lower dimensional values the results appear slightly different that the df version. Boh?).  
Also, not sure what are the heatmaps on the upper part of the grid, but once colored properly they look nice.

**AlgebraOfGraphics**  
So far this is the farthest I have got to. Maybe my experience with ggplot helps. I got my plot with all of the 13th columns with no crash. Pumas documentation on AoG was a great help as well (should be publicised more!).  
Only problem I was not able to find how to get a density histogram in the middle diagonal.  
HELP PLEASE!!!  
This is the crucial part of the plot:

```julia
plt = data(df) * (visual(Scatter; color=:dodgerblue) + linear() * visual(; color=:red)) * mapping(cols, permutedims(cols), col=dims(1), row=dims(2))
fg = draw(
    plt,
    figure=(figure_padding=0, size=(1500, 1500))
)

```

**Makie**  
I found an old version of code here in Julia Discourse. Sadly Makie has changes a lot its syntax since (probably more than once) and I couldn’t find any good documentation on how to do these type of plots nor any docs on migrating from older versions (what the heck is LAxis?!? is it dead or still used??).  
I reproduce the plot code here if somebody can help in bringing it up to current.  
HELP PLEASE!!!

```julia
function pairplot(df)
    dim = size(df, 2)-1

    scene, layout = layoutscene(30, resolution = (900, 900))
    axs = layout[1:dim, 1:dim] = [LAxis(scene) for i in 1:dim^2]
    x = 0
    for i in 1:dim, j in 1:dim  
	      
	if i == j
	    x+=1
	    plt = plot!(axs[x],Position.stack, histogram, Data(df), Group(:class), df[:, i])
	else
	    x+=1
	    plt = Makie.scatter!(axs[x], Data(df), Group(:class), df[:,j], df[:,i])    
	end
    end
    scene
end
(from https://discourse.julialang.org/t/makie-pairplot/39298/3)

```

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [December 23, 2023, 12:55pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/2 "2023-12-23T12:55:49Z")

</div>

`LAxis` comes from MakieLayout.jl. Here are the docs: [LAxis · MakieLayout.jl](https://jkrumbiegel.com/MakieLayout.jl/v0.9/laxis/)

Hope this helps, I am no Makie.jl expert, I only use (GL)Makie for interactive 3D stuff 😉

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [December 23, 2023, 1:37pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/3 "2023-12-23T13:37:35Z")

</div>

LAxis was the old name for Axis before MakieLayout got fully integrated.

Check out [GitHub - sefffal/PairPlots.jl: Beautiful and flexible vizualizations of high dimensional data](https://github.com/sefffal/PairPlots.jl) which is based on Makie

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [December 23, 2023, 1:51pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/4 "2023-12-23T13:51:59Z")

</div>

Try with [Gnuplot.jl](https://github.com/gcalderone/Gnuplot.jl/):

```julia
using RDatasets, Gnuplot
df = dataset("datasets", "iris")[:, 1:4]

@gp "set multiplot layout $(ncol(df)), $(ncol(df)) margins 0.1, 0.9, 0.15, 0.9 spacing 0.01 columnsfirst upward" :-
id = 1
for ix in 1:ncol(df)
    for iy in 1:ncol(df)
        (iy == 1) && (@gp :- id xlab=names(df)[ix] "set xtics format '% h'" :-)
        (ix == 1) && (@gp :- id ylab=names(df)[iy] "set ytics format '% h'" :-)

        xr = [extrema(df[:, ix])...]
        yr = [extrema(df[:, iy])...]
        if ix == iy
            @gp :- id xr=xr yr=[NaN,NaN] hist(df[:, ix], range=xr, nbins=5) :-
        else
            @gp :- id xr=xr yr=yr df[:, ix] df[:, iy] "w p notit" :-
        end
        id += 1
        @gp :- id xlab="" ylab="" "set xtics format ''" "set ytics format ''" :-
    end
end
@gp

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/6/c/6c6e1239bc83f3b8f4ed503211e01e7fc98689bd.png)

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [December 23, 2023, 3:30pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/5 "2023-12-23T15:30:03Z")

</div>

Another option  
[https://www.generic-mapping-tools.org/GMTjl\_doc/examples/plotting\_functions/05\_1\_stats/#example\_6265284708922005600](https://www.generic-mapping-tools.org/GMTjl_doc/examples/plotting_functions/05_1_stats/#example_6265284708922005600)

---

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 23, 2023, 7:58pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/6 "2023-12-23T19:58:30Z")

</div>

@joa-quim thanks for the suggestion. Sadly GMT crashes with the Boston Housing dataset (but works with IRIS).

Issue reported here: [cornerplot fails with Boston Housing dataset · Issue #1333 · GenericMappingTools/GMT.jl · GitHub](https://github.com/GenericMappingTools/GMT.jl/issues/1333)

---

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 23, 2023, 8:13pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/7 "2023-12-23T20:13:41Z")

</div>

@gcalderone thanks for the suggestion!.

Good news: it works with the Boston Housing dataset (i.e, does not crash!). IT is also very fast.

The graphics are a bit primitive, but I’ll try to clean it a bit.

It should ring a wake-up call bell of sort for the community: so far is the only plot package that works fully (i.e. including density plots on longest diagonal), but is a package dating back to 1986, according to wikipedia!

Nice and rich visualizations would certainly help to attract R and Python users.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 23, 2023, 9:01pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/8 "2023-12-23T21:01:05Z")

</div>

> **[GitHub - sefffal/PairPlots.jl: Beautiful and flexible vizualizations of high...](https://github.com/sefffal/PairPlots.jl)**
>
> Beautiful and flexible vizualizations of high dimensional data - GitHub - sefffal/PairPlots.jl: Beautiful and flexible vizualizations of high dimensional data

> **[Guide · PairPlots.jl](https://sefffal.github.io/PairPlots.jl/dev/guide/)**
>
> Documentation for PairPlots.jl.

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [December 23, 2023, 11:57pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/9 "2023-12-23T23:57:21Z")

</div>

I added a new example in the [documentation](https://gcalderone.github.io/Gnuplot.jl/stable/recipes/#Corner-plot-recipe).

> [@enzomar](#):
>
> The graphics are a bit primitive, but I’ll try to clean it a bit.

I typically use the following global settings to obtain a reasonably nice output:

```julia
Gnuplot.options.term = "wxt size 700,400";
push!(Gnuplot.options.init, Gnuplot.linetypes(:Set1_5, lw=1.5, ps=1.5));

```

> [@enzomar](#):
>
> It should ring a wake-up call bell of sort for the community: so far is the only plot package that works fully (i.e. including density plots on longest diagonal), but is a package dating back to 1986, according to wikipedia!

1986 yes, but [as you can see](http://gnuplot.info/) the latest version has been released two months ago, and they are working on the new version 6.1.

I agree it looks a bit old-fashioned, but it also is extremely powerful and easy to use.  
IMHO it is not easy to catch up 40 years of development… 😉

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [December 24, 2023, 1:04am UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/10 "2023-12-24T01:04:30Z")

</div>

Yeah I think they might have overlooked my link 🙂

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [December 24, 2023, 3:34am UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/11 "2023-12-24T03:34:30Z")

</div>

Not a crash but instead a corner case in the parser to the GMT syntax that lead to a wrong decision of how to interpret the generated command. That’s what this message mean

```julia
]: Cannot tell if -T1 -W0.1 is new or deprecated syntax; selected deprecated.
histogram [ERROR]: Unrecognized option -T

```

Fixed in master and now it produces this. Still not perfect due to the number of subplots. I wonder what best solution is in these type of cases.

Note, the _Z’s_ result from the fact that `M = Matrix(df[:, 1:end-1])` lost the column names in original data.

 ![GMTplot](https://global.discourse-cdn.com/julialang/original/3X/8/5/85ad82858b850f24bad8b79ed199c5d6b15d0134.jpeg)

---

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 24, 2023, 3:56pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/12 "2023-12-24T15:56:45Z")

</div>

Thanks @jules for the link. I’ll try it and report.

---

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 24, 2023, 4:02pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/13 "2023-12-24T16:02:50Z")

</div>

@joa-quim I got the same result, which is good. Oddly I got in on a saved image, while the same code for IRIS was reproducing inline in my jupyterlab notebook.

Is there a reason why the same code renders in a saved image in one case and inline in the other?  
Moreover, I use a Matrix as this is what the GMT function expect. hence no real variable name but only dummy ones. Do you have any suggestion on how to get the actual dataframe column names of the variables outside of the plot?

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [December 24, 2023, 5:54pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/14 "2023-12-24T17:54:18Z")

</div>

A quick before Christmas dinner answer. Need to commit further changes to deal with names easier.  
Try  
GMT.df2ds(df) instead of Matrix

---

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 26, 2023, 10:57pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/15 "2023-12-26T22:57:44Z")

</div>

An update:

GOOD: I built a good correlogram with Plots and I’m quite satisfied with it: it is very close to optimal.

BAD: Again (and perhaps not surprisingly as it was happening with StatsPlots) crashes with more than 11 variables / columns.

I just reported it on Github here: [[BUG] Plots crashes and julia hangs plotting correlogram with \>12 columns on Boston housing dataset · Issue #4856 · JuliaPlots/Plots.jl · GitHub](https://github.com/JuliaPlots/Plots.jl/issues/4856)

Next I will test PairPlots (as it is built on Makie I’m moderately optimist).

If there’s any good Makie chap around I would still like to test this on native Makie but I need HELP to migrate the code I posted above.

Many thanks in advance.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 26, 2023, 11:21pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/16 "2023-12-26T23:21:21Z")

</div>

> [@enzomar](#):
>
> BAD: Again (and perhaps not surprisingly as it was happening with StatsPlots) crashes with more than 11 variables / columns.

In case it helps, for a large number of subplots, the plotly() backend is best. [See example here](https://discourse.julialang.org/t/grid-of-differently-colored-scatter-plots/74202/2).

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [December 27, 2023, 7:52am UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/17 "2023-12-27T07:52:34Z")

</div>

The thread you got your non-working Makie version from had other, newer examples (plus the PairPlots.jl link that I posted here as well) but anyway, here’s the example from above modified a bit for current Makie. This doesn’t do any grouping, though, which is why something like PairPlots saves you work.

```julia
using CairoMakie

function pairplot(df)
    dim = size(df, 2)-1

    f = Figure(size = (900, 900), fontsize = 10)

    # don't update layout with every new axis, that's slow
    with_updates_suspended(f.layout) do
        axs = [Axis(f[i, j]) for i in 1:dim, j in 1:dim]
        
        x = 0
        for i in 1:dim, j in 1:dim  
            x+=1
            if i == j
                hist!(axs[x], df[:, i])
            else
                scatter!(axs[x], df[:,j], df[:,i])    
            end
        end
    end
    
    f
end

df = randn(100, 10)

pairplot(df)

```

 ![grafik](https://global.discourse-cdn.com/julialang/original/3X/f/e/fe872fa5bd6cf971a515d30006de26cfc9167abd.jpeg)

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [December 27, 2023, 10:47am UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/18 "2023-12-27T10:47:40Z")

</div>

[PairPlot.jl](https://github.com/sefffal/PairPlots.jl) cited several times above seems very capable indeed. I’d recommend to look at its announcement thread to get a better idea of its potential

> [@\[ANN\] A Package for Generating Corner Plots (PairPlots.jl)](https://discourse.julialang.org/t/ann-a-package-for-generating-corner-plots-pairplots-jl/58542):
>
> [A Package for Generating Corner Plots](https://github.com/sefffal/CornerPlots) (PairPlots.jl) Corner plots are a useful way of visualizing high dimensional data by presenting a grid of 2D histograms comparing each pair of variables. This package aims to provide a flexible interface for generating these grids, but by default aims to reproduce as closely as possible the output of [corner.py](https://corner.readthedocs.io/en/latest/). Usage: using Plots, PairPlots a = randn(1000) b = randn(1000) data = (;a, b) corner(data) This is built on RecipesBase rather than Plots direc…

---

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 28, 2023, 1:17pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/19 "2023-12-28T13:17:30Z")

</div>

PairPlots!

I eventually got around to text PairPlots.

GOOD:

- It doesn’t crash with the full 14 columns of the Boston housing dataset!
- Prints the column names on the edges: nice!
- Plots Truth lines out-of-the-box

NOT so GOOD:

- I couldn’t find a way to get out-of-the-box a trendline (a classing LR line like AoG or Plots).
- It seems that histogram binning is a complex affair, possible but not out-of-the-box
- Scatter plot: requires HexBin + Scatter (not entirely sure why not just one func?)

```julia
pairplot(
    df => (
        PairPlots.HexBin(colormap=Makie.cgrad([:transparent, :green])),
        PairPlots.Scatter(), 
        PairPlots.MarginHist(color=:blue),
        PairPlots.MarginConfidenceLimits(),
    )
)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/3/0312e35f7f8955f64aa335863143f835e6a2db84.jpeg)

---

<div class="post-metadata">

**Author:** ![enzomar](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@enzomar](https://discourse.julialang.org/u/enzomar)\
**Post date:** [December 28, 2023, 1:19pm UTC](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971/20 "2023-12-28T13:19:49Z")

</div>

Thanks @jules this looks great!

I think I should be able to add column names programmatically.

The only issue I can see is that I couldn’t find in Makie a way to add a trend line out-of-the-box (perhaps not surprisingly the same occurs with PairPlots).

[Next page](https://discourse.julialang.org/t/failing-to-plot-correlograms-in-julia-makie-vs-aog-vs-statsplots/107971.md?page=2)
