Subplots with one common legend

I am trying to plot many subplots with one common legend that is not on the subplots but in between the two subplot rows where it is empty. Moreover, it should not enlarge the space between the row and make the plot unnecessary larger.

using Plots
pyplot();
D = 10
K = 4
θ = range(0, stop=2π, length=50)
r(θ) = 1 + cos(θ) * sin(θ)^2
p = [plot(proj=:polar) for j in 1:D]
[[plot!(p[j], θ, r.(θ)+0.2*rand(length(θ)), label =:none) for k in 1:K] for j in 1:D]
plot(p...,size=(1200,600), layout = (2,5))

I would like to achieve something like that

This seems to have already been addressed in this post.

Thanks for the link. Unfortunatly if I understand, the solution was to change the layout to add an empty subplot with only the legend. Here I don’t want to touch my layout. I just want to superpose the legend to the grid of subplots.

I think I found my answer manipulating inset plots. It just adds one line, so I think it is more robust than changing the layout, and you really can put the legend anywhere on the plot. (Drawback you might have to adjust manually the position).

D = 10
K = 4
θ = range(0, stop=2π, length=50)
r(θ) = 1 + cos(θ) * sin(θ)^2
p = [plot(proj=:polar) for j in 1:D]
[[plot!(p[j], θ, r.(θ)+0.2*rand(length(θ)), label =:none) for k in 1:K] for j in 1:D]
pall = plot(p...,size=(1200,600), layout = (2,5))
plot!(pall, (1:K)', inset = (1, bbox(2.25,0.8,0.3,0.3)), background_color=:transparent, subplot = D+1, legendfontsize=11, framestyle = :none, label=permutedims("k=".*string.(1:K)))

I am not exactly sure how to control the size of the legend box (it does not change with bbox) but with ‘legendfontsize’ and ‘background_color’ it is perfect for my application.

1 Like

Excellent.

NB: by editing the last line as follows the legend looks better on my display if using Plots; gr():

plot!(pall, (1:K)', inset = (1, bbox(1.65,0.87,1.0,1.0)), background_color=:transparent,
      subplot=D+1,legendfontsize=11,framestyle=:none,label=permutedims(" k=".*string.(1:K).*" "))

and if one wants to remove the border of the inset:

plot!(pall, (1:K)', inset = (1, bbox(1.65,0.87,1.0,1.0)), background_color=:transparent,
      subplot=D+1,legendfontsize=11,framestyle=:none,label=permutedims(" k=".*string.(1:K).*" "),
      foreground_color_legend = nothing)