11

I would like to add a global title to a group of subplots using Plots.jl.

Ideally, I'd do something like:

using Plots
pyplot()
plot(rand(10,2), plot_title="Main title", title=["A" "B"], layout=2)

but, as per the Plots.jl documentation, the plot_title attribute is not yet implemented:

Title for the whole plot (not the subplots) (Note: Not currently implemented)

In the meanwhile, is there any way around it?

I'm currently using the pyplot backend, but I'm not especially tied to it.

Nicolas Payette
  • 14,847
  • 1
  • 27
  • 37
  • 1
    You can use an annotation to put in text. Just center it where the plot would be an make it big. – Chris Rackauckas Mar 28 '17 at 10:57
  • Annotations, as far as I can tell, must be placed with data coordinates, and do not appear at all if I try to place them outside a plot. They also seem to apply to every subplots. How I could use one to make a title is not at all clear to me. What I am missing? – Nicolas Payette Mar 29 '17 at 08:16
  • You used to be able to do this I think, but currently, I don't think you can. @ChrisRackauckas what were you thinking about doing here? annotate! will annotate all subplots. – pkofod Mar 29 '17 at 08:29
  • I didn't know that it will disappear if it's out of the subplot. That puts a damper on things. – Chris Rackauckas Mar 29 '17 at 09:15
  • Plot_title works now! – Matt Krause Oct 25 '21 at 19:54

4 Answers4

8

This is a bit of a hack, but should be agnostic to the backend. Basically create a new plot where the only contents are the title you want, and then add it on top using layout. Here is an example using the GR backend:

# create a transparent scatter plot with an 'annotation' that will become title
y = ones(3) 
title = Plots.scatter(y, marker=0,markeralpha=0, annotations=(2, y[2], Plots.text("This is title")),axis=false, grid=false, leg=false,size=(200,100))

# combine the 'title' plot with your real plots
Plots.plot(
    title,
    Plots.plot(rand(100,4), layout = 4),
    layout=grid(2,1,heights=[0.1,0.9])
)

Produces:

enter image description here

Alec
  • 4,235
  • 1
  • 34
  • 46
7

More recent versions of Plots.jl support the plot_title attribute, which provides a title for the whole plot. This can be combined with individual titles of individual plots.

using Plots   

layout = @layout [a{0.66w} b{0.33w}]
LHS = heatmap(rand(100, 100), title="Title for just the heatmap")
RHS = plot(1:100, 1:100, title="Only the line")
plot(LHS, RHS, plot_title="Overall title of the plot")

Alternatively, you can set the title for an existing plot directly.

p = plot(LHS, RHS)
p[:plot_title] = "Overall title of the plot"
plot(p)

Example plot, produced by the code above

Matt Krause
  • 1,113
  • 14
  • 31
1

When using the pyplot backend, you can use PyPlot commands to alter a Plots figure, cf. Accessing backend specific functionality with Julia Plots.

To set a title for the whole figure, you could do something like:

using Plots
p1 = plot(sin, title = "sin")
p2 = plot(cos, title = "cos")
p = plot(p1, p2, top_margin=1cm)
import PyPlot
PyPlot.suptitle("Trigonometric functions")
PyPlot.savefig("suptile_test.png")

One needs to explicitly call PyPlot.savefig to see the effect of the PyPlot functions.

Note that all changes made using the PyPlot interface will be overwritten when you use a Plots function.

Community
  • 1
  • 1
tim
  • 2,076
  • 8
  • 14
  • Sorry for taking so long to accept your answer: your example works fine, but in my real world use case, trying to use `PyPlot.suptitle` caused the _rest_ of the plot to disappear. I never figured out why. I ended up switching to Gadfly (not just for that). Thanks for your help! – Nicolas Payette Apr 20 '17 at 12:51
0

subplots are fields of the Plot type, and each subplot has a field called :attr that you can modify and re-display() the plot. Try the following:

julia> l = @layout([a{0.1h} ;b [c; d e]])
Plots.GridLayout(2,1)

julia> p = plot(randn(100,5),layout=l,t=[:line :histogram :scatter :steppre :bar],leg=false,ticks=nothing,border=false)

julia> p.subplots
5-element Array{Plots.Subplot,1}:
 Subplot{1}
 Subplot{2}
 Subplot{3}
 Subplot{4}
 Subplot{5}

julia> fieldnames(p.subplots[1])
8-element Array{Symbol,1}:
 :parent     
 :series_list
 :minpad     
 :bbox       
 :plotarea   
 :attr       
 :o          
 :plt

julia> for i in 1:length(p.subplots)
           p.subplots[i].attr[:title] = "subtitle $i"
       end

 julia> display(p)

You should now see a title in each subplot

Jean Marie
  • 190
  • 1
  • 6
  • 5
    This is not at all what he's asking about though, he wants one title for the whole plot and then subtitles. – pkofod Mar 29 '17 at 07:55
  • 1
    Thanks for the answer, but @pkofod is right: I'm looking for one big title above all the subplots, not one title for each subplot. – Nicolas Payette Mar 29 '17 at 08:17
  • Sorry for the hasty response, I was just working on subplot titles when I saw the question and failed to read it through. matplotlib's `Figure` object has a `suptitle` property, and although you can access and set that through p.o[:suptitle] it doesn't want to display the title. – Jean Marie Mar 29 '17 at 08:42
  • No problem! And yeah, I tried accessing `suptitle`, but couldn't get it to work either. – Nicolas Payette Mar 29 '17 at 08:57
  • @tim: thanks for pointing out `savefig` requirement and link! – Jean Marie Mar 30 '17 at 13:23