Super title in Plots and subplots


I am having a hard time understanding how to organize titles in Plots.jl using pyplot().

I have 2X2 subplots and I would like to have a title for each subplot, one for each horizontal pair, and one for the overall plot. How can I do that?




as you probably figured out, there is no problem of having a title per plot.
It is set by a simple title option.

The others are not possible to add by Plots.jl options as far as I can tell.
At least, you can always get a matplotlib object and act on it directly.

using Plots

plot!(x->x^2, -1, 2, sp=1, title="Title 1", frame=:box)
plot!(x->x^2, -1, 2, sp=2, title="Title 2", frame=:box)
plot!(x->x^2, -1, 2, sp=3, title="Title 3", frame=:box)
plot!(x->x^2, -1, 2, sp=4, title="Title 4", frame=:box)

plt = plot!()
fig = plt[3][1][:plot_object].o
children = fig[:get_children]()
ax = children[2]
ax[:text](0.6, 1.2, "My Big Title", fontsize=22, transform=ax[:transAxes], verticalalignment="bottom")

It feels ugly, I know.


Thanks. Just to be clear, this code generates a title for the whole plot, but not for each row, right?

The documentation mentions a plot_title attribute which has not yet been implemented, but I assume it will be eventually. In the meantime, you can use a subplot containing only a title as a workaround:

using Plots
title = plot(title = "Plot title", grid = false, showaxis = false, bottom_margin = -50Plots.px)
p1 = scatter(rand(5, 1), title = "Subplot 1")
p2 = scatter(rand(5, 1), title = "Subplot 2")
plot(title, p1, p2, layout = @layout([A{0.01h}; [B C]]))



Thanks, this will do. Still surprised that Plots is missing very basic features.


Has anyone developed a better solution? The reported solutions require a lot of manual adjustment of the margins and can result in truncation of subplots.

@Christopher_Fisher, could you provide an example of the truncation observed?

Herein a variant of the last solution, in case it might work better for your use case:

using Measures, Plots; gr()

l = @layout [a{0.01h}; grid(2,2)]
p = fill(plot(),5,1)
p[1] = plot(title="Supertitle",framestyle=nothing,showaxis=false,xticks=false,yticks=false,margin=0mm)
[p[i+1] = plot(1:10,rand(10),framestyle=:default,lc=rand(1:20),label="$i",title="title $i") for i in 1:4]
plot(p..., layout=l)


1 Like

Hi @rafael.guerra,

I think there were a few issues. First, bottom_margin = -50Plots.px from kdyhage’s code was causing truncation. I set this value to zero to fix that problem. I’m not sure if that might be useful in other cases. I also encountered some issues with subtitles being placed on top of the x-axis title of the plot above. I solved that with margin=10mm. I’m not sure why that happens in some cases but not others. Sorry that I do not have examples of the problem that can be shared. In any case, modifying those two parameters may help others in the future.

I am reviving this topic for a small update, as I came across this topic trying to solve the same problem, and this wasn’t the best solution:

There is now the plot_title command, so you can do simply:

using Plots

p1 = scatter(rand(5, 1), title = "Subplot 1")
p2 = scatter(rand(5, 1), title = "Subplot 2")
plot(p1, p2, layout = @layout([B C]), plot_title="Plot title")

which gives



How can you the control the position of the Plot title? Right now it is very close to the subplots.

1 Like

I think you can’t with plot_title (yet), but I may be wrong. If you want to have more control on the position, I still think @rafael.guerra is the best solution.

Actually it is possible to control the “vspan” of the plot_title with the plot_titlevspan attritbute which takes a number in the interval [0,1] defining the percentage of the figure that has to be reserved for the title.
As an extreme example:

using Plots

p1 = scatter(rand(5, 1), title = "Subplot 1")
p2 = scatter(rand(5, 1), title = "Subplot 2")
plot(p1, p2, layout = @layout([B C]), plot_title="Plot title", plot_titlevspan=0.5)

produces the following output: