Common legend for subplots

Hi all,

I have a follow up question to this ongoing issue about using a common legend across subplots. In my use case, a vector of plots with an unknown length are combined into a grid of subplots. Subplots do not necessarily have the same factors in the legend, but I need the legend key to be consistent. For example, “A” must be mapped to blue in all subplots even if some subplots do not contain “A”.

I am having trouble getting the hack in the previous post to work. The legend does not show up and there is an extraneous blank subplot. Is there a better solution?



using DataFrames, StatsPlots, Random 

function f(x, y)
    if x ≤ .5 && y ≤ .5
        return 1
    elseif x > .5 && y ≤ .5
        return 2
    elseif x ≤ .5 && y > .5
        return 3
        return 4

df1 = DataFrame(x =rand(100), y=rand(100))
df2 = DataFrame(x =rand(100)*.5, y=rand(100))
transform!(df1, [:x,:y]=> ByRow(f) => :quadrant)
transform!(df2, [:x,:y]=> ByRow(f) => :quadrant)

p1 = @df df1 scatter(:x, :y, color=:quadrant, leg=false, ylims=(0, 1),xlims = (0,1))
p2 = @df df2 scatter(:x, :y, color=:quadrant, leg=false, ylims=(0, 1),xlims = (0,1))
plots = [p1,p2]
plot(plots..., plot(legend=true, framestyle=:none))

Would a single legend like this be helpful?

1 Like

Thanks for your reply! Yes. I am looking for something like that.

With no bells and whistles.

using DataFrames, Random, StatsPlots; gr(dpi=600)

function f(x, y)
    x ≤ .5 && y ≤ .5 ? 1 :
    x > .5 && y ≤ .5 ? 2 :
    x ≤ .5 && y > .5 ? 3 : 4

n = 4
df = [DataFrame(x =rand(100)*rand((1,0.5)), y=rand(100)*rand((1,0.5))) for _ in 1:n]
[transform!(df, [:x,:y]=> ByRow(f) => :quadrant) for df in df]

p = [@df d scatter(:x, :y, color=:quadrant, ms=3, msw=0.3, lims=(0, 1), ratio=1) for d in df]

colors = palette(:default)[1:n]'
labels = ["\n  Quadrant-1\n" "\n  Quadrant-2\n" "\n  Quadrant-3\n" "\n  Quadrant-4\n"]
l = @layout  [grid(2,2) a{0.2w}]
p0 = scatter((-n:-1)',(-n:-1)', lims=(0,1), legendfontsize=7, legend=:left,
        fg_color_legend = nothing, label=labels, fc=colors, frame=:none);
plot(p..., p0, layout=l, size=(800,500))

Thank you!

1 Like