Hi. I have a custom data type which, after doing some calculations on, I would like to plot in a specific way. A basic example of the setup is this:
struct Data
x
y1s
y2s
end
x = 1:10
y1s = [[rand(10) for _ in 1:5] for _ in 1:3]
y2s = [[rand(10) for _ in 1:5] for _ in 1:3]
data = Data(x, y1s, y2s)
What I would like is an nxm grid of subplots, where each subplot has its own title, and each row has a title for that entire row. Below is an mspaint of what I want:
I can get pretty close with nested plot
s, but I have two problems:
- This requires my package to have a dependency on
Plots
, which I would like to avoid. - This method also causes the legend to contain duplicate labels, one for each individual subplot.
This is my attempt with Plots
:
using Plots
plotly()
titles = ["Title $k" for k in 1:5]
supertitles = ["SuperTitle $k" for k in 1:3]
ps_all = []
for k in 1:3
ps = []
for i in 1:5
# Process the signals in some way
y1 = data.y1s[k][i] .+ k
y2 = data.y2s[k][i] .+ k
# Create a single plot of of one x vs 2 ys, add a title to each
push!(ps, plot(data.x, [y1, y2], title=titles[i], lab=["signal1" "signal2"]))
end
# Plot all three x vs ys plots in one row, add a super title
push!(ps_all, plot(ps..., plot_title=supertitles[k], layout=(1, 5), size=(250*3, 250)))
end
# Plot all five rows of three plots, each row with its own super title
plot(ps_all..., layout=(3, 1), size=(250*5, 250*3), legend=:outertopright)
To solve (1), I tried doing the same thing with RecipesBase
. I am not very familiar with this, so I’m not really sure what I’m supposed to be doing. In any event, the legend is not placed where I want it, the plot_title
element is squashed together with the regular title
s, and I cannot plot all the rows together - they all end up sharing subplots on one row.
using RecipesBase
titles = ["Title $k" for k in 1:5]
supertitles = ["SuperTitle $k" for k in 1:3]
# Create (user?) recipe for a single row
@recipe function f(data::Data, k::Integer)
ncol = length(data.y1s[k])
layout := (1, ncol)
size := (250*ncol, 250)
plot_title := supertitles[k]
legend := :outertopright
for i in 1:ncol
@series begin
subplot := i
title := titles[i]
labels := ["signal1" "signal2"]
y1 = data.y1s[k][i] .+ offsets[k]
y2 = data.y2s[k][i] .+ offsets[k]
data.x, [y1, y2]
end
end
end
# Try plotting single row
plot(data, 1)
# Problem: plot_title is squashed together with the regular titles, and the legend is not placed in the outertopright
# Create (user?) recipe for all the rows
@recipe function f(data::Data)
nrow = length(data.y1s)
ncol = length(data.y1s[1])
layout := (nrow, 1)
size := (250*ncol, 250*nrow)
for k in 1:nrow
@series begin
subplot := k
data, k
end
end
end
# Try plotting all rows
plot(data)
I don’t know how to solve (2). Does anyone know how to solve these problems, or what I should be doing instead to get the result I want?