How to make a Pair Plot in Plots.jl?

Hey everyone,

I feel like I am totally overthinking this but am running into a wall. I was able to make a pairplot using some code from a Makie discussion here. I have been trying to do the same thing using Plots.jl. Instead, I am having some errors translating my logic to Plots.jl. Here is my current attempt:

using DataFrames
using Plots

# Nonsense Data
df = DataFrame([1 2 3; 2 4 6; 3 6 9])

function pairplot(df)
    rows, cols = size(df)
    scatter([row for row in 1:rows], [col for col in 1:cols],
        layout = (rows, cols))
end

pairplot(df)

Which produces the following:

It’s the right form but only the first plot is plotted. Going from there, I used the documentation from Plot.jl’s documentation where about layouts where it discussed incrementally generating plots and adding them to a final plot:

using DataFrames
using Plots

df = DataFrame([1 2 3; 2 4 6; 3 6 9])

function pairplot(df)
    rows, cols = size(df)
    plots = []
    for row = 1:rows, col = 1:cols
        push!(plots, scatter(row, col))
    end
    plot([p for p in plots], layout = (rows, cols))
end

pairplot(df)

This throws an error which somewhat surprised me based on the documentation.

ERROR: LoadError: MethodError: no method matching Plots.Plot{Plots.GRBackend}(::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::C
har, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Ch
ar, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char, ::Char)
Closest candidates are:
  Plots.Plot{Plots.GRBackend}(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any) where T<:AbstractBackend at /home/cedarprince/.julia/packages/Plots/lmp2A/src/types.j
l:68
Stacktrace:
 [1] apply_recipe(::Dict{Symbol,Any}, ::Type{Plots.Plot{Plots.GRBackend}}, ::Plots.Plot{Plots.GRBackend}) at /home/cedarprince/.julia/packages/Plots/lmp2A/src/recipes.jl:50
 [2] _apply_type_recipe(::Any, ::AbstractArray, ::Any) at /home/cedarprince/.julia/packages/RecipesPipeline/uPBKQ/src/type_recipe.jl:39
 [3] macro expansion at /home/cedarprince/.julia/packages/RecipesPipeline/uPBKQ/src/user_recipe.jl:149 [inlined]
 [4] apply_recipe(::AbstractDict{Symbol,Any}, ::Any) at /home/cedarprince/.julia/packages/RecipesBase/92zOw/src/RecipesBase.jl:282
 [5] _process_userrecipes!(::Any, ::Any, ::Any) at /home/cedarprince/.julia/packages/RecipesPipeline/uPBKQ/src/user_recipe.jl:36
 [6] recipe_pipeline!(::Any, ::Any, ::Any) at /home/cedarprince/.julia/packages/RecipesPipeline/uPBKQ/src/RecipesPipeline.jl:70
 [7] _plot!(::Plots.Plot, ::Any, ::Any) at /home/cedarprince/.julia/packages/Plots/lmp2A/src/plot.jl:172
 [8] plot(::Any; kw::Any) at /home/cedarprince/.julia/packages/Plots/lmp2A/src/plot.jl:58
 [9] pairplot(::DataFrame) at /home/src/Projects/COVID_MOBILITY_ANALYTICS/_research/pair.jl:12
 [10] top-level scope at /home/src/Projects/COVID_MOBILITY_ANALYTICS/_research/pair.jl:15
 [11] include(::String) at ./client.jl:457
 [12] top-level scope at REPL[34]:1
in expression starting at /home/src/Projects/COVID_MOBILITY_ANALYTICS/_research/pair.jl:15

Would anyone be willing to help me out with this? Thank you!

~ tcp :deciduous_tree:

1 Like

I think the only thing you would need to add, are three points directly after the closing brackets, like shown here.

function pairplot(df)
    rows, cols = size(df)
    plots = []
    for row = 1:rows, col = 1:cols
        push!(plots, plot(row, col))
    end
    plot([p for p in plots]..., layout = (rows, cols))
end

image

1 Like

[p for p in plots] is just a cumbersome way to write copy(plots). You don’t even need it, plots... will do what you want.

1 Like

Hey @dave7895 and @FPGro - super appreciate your answers! That did trick! For anyone else curious, here is how I plotted a pair plot

using DataFrames
using Plots

df = rand(5, 5) * 10 |> DataFrame

function pairplot(df)
    rows, cols = size(df)
    plots = []
    for row = 1:rows, col = 1:cols
        push!(
            plots,
            scatter(
                df[row],
                df[col],
                xtickfont = font(4),
                ytickfont = font(4),
                legend = false,
            ),
        )
    end
    plot(plots..., layout = (rows, cols))
end

pairplot(df)

which gives

1 Like