This is a really interesting discussion, and it made me start looking for out-of-the box solutions that might be floating around already. I see that @rafael.guerra also has a similar post using StatsPlots.jl, but I guess the problem there is that some extra work would still need to be done to hide shared axis decorations and switch from an auto generated legend to a title? Trying it out on the above still gets us pretty far I think:
using Plots, DataFrames, Dates
dfd = DataFrame(
Date = (today() + Day(1)) : Day(1) : (today() + Day(60)),
Return = randn(60) / 100.0,
A = repeat(1:5; inner=12),
B = repeat(1:12; inner=5),
)
@df dfd Plots.plot(:Date, :Return;
group = {B = :B},
layout = 12,
size = (1_000, 700),
rotation = 45,
xtickfontsize = 6,
ytickfontsize = 6,
plot_title = "Hello",
ylims = extrema(:Return),
)
This made me curious if AlgebraOfGraphics could get us the rest of the way there, but it looks like there are a couple of trade-offs, IIUC:
using CairoMakie, AlgebraOfGraphics
plt = data(dfd) * mapping(:Date, :Return;
layout = :B => nonnumeric,
) *
visual(Lines)
fg = draw(plt;
figure = (; resolution = (1_000, 700)),
axis = (;
xticklabelrotation = π/4,
yticklabelrotation = π/4,
xticks = datetimeticks(identity, dfd.Date),
xticklabelsize = 10,
yticklabelsize = 10,
),
facet = (; linkxaxes=:none),
)
Label(fg.figure[0, :], "Hello";
textsize = 28,
font = AlgebraOfGraphics.firasans("Medium"),
)
fg
A few of the benefits include computing the number of subplots we need automatically, hiding shared axis decorations, handling the global data limits, and applying common axis labels. The remaining downsides I am seeing are that we need to manually specify the xticks with a helper function for now, and stick to numerical facet labels to get the ordering right (i.e., doing something like layout = :B => (x -> "B = $x")
would change the ordering according to sort(string.(1:12))
, instead of following the natural sorting via something like NaturalSort.jl). I could be misunderstanding some of the more technical points here, so maybe @piever might have a better solution?
Anyway, I’m realizing that this thread was originally about Plots.jl, so I’d be happy to split this discussion off if that would be better