Common x-/y-label in Plots.jl

Hello everyone,

I was wondering if there is a way to specify a common x- or y-label easily in Plots.jl when plotting one figure with multiple subplots.
The following creates subplots with the same axes labels for both figures, but printed for each figure:

using Plots

p1 = plot(rand(100))
p2 = plot(rand(100))

testplot = plot(p1, p2, link=:both, xlabel="X", ylabel="Y", layout=(2,1))

Is there a way to print both the x- and y-label just once?

1 Like

Hm. I’ve never seen the link keyword for plot, so it is not quite clear to me what that means. In a case like this, I’d do the following:

using Plots

p1 = plot(rand(100))
p2 = plot(rand(100),xlabel="X")

plot(p1,p2,layout=(2,1),ylabel="Y")

This gives a shared xlabel, but it gives one ylabel for each sub plot. I find that natural, but it is perhaps not exactly what you want.

Thanks for the reply!

The link keyword determines which axis limits are shared between plots.
In this case :both means both the x- and y-limits are shared.

I do wonder if there is a more general / easier solution though. Seems like something Plots.jl should be able to handle…

I would find this useful as well – for grid layouts that is. It would not be hard to write a function that does this, but it would a bit fragile (dependent on internals of Plots.jl). Something like:

using Plots

function ylabels_from_grid(l :: Plots.GridLayout, yStr)
    n = length(l.grid)
    nCols = size(l.grid, 2)
    yV = fill("", n);
    for j = 1 : n
        if rem(j, nCols) == 1
            yV[j] = yStr;
        end
    end
    return yV    
end

# Make a layout
l = @layout grid(2,2);
yV = ylabels_from_grid(l, "Y label");

# Plot some things
pV = Vector{Any}(undef, 4)
for j = 1 : 4
    pV[j] = plot(1:10, 1:10, xlabel = "$j", ylabel = yV[j])
end
p = plot(pV..., layout = l)

link is especially useful if you use the interactive plots of Plotly (by calling plotly() before you make your plot) so that when you zoom into one subplot, the other plots stay synchronized.