# Plot recipes with nested subplots

**URL:** <https://discourse.julialang.org/t/plot-recipes-with-nested-subplots/130465>\
**Category:** Visualization\
**Tags:** question, plotting\
**Created:** [July 4, 2025, 8:20am UTC](https://discourse.julialang.org/t/plot-recipes-with-nested-subplots/130465 "2025-07-04T08:20:08Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![polhager](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/polhager/32/37340_2.png) [@polhager](https://discourse.julialang.org/u/polhager)\
**Post date:** [July 4, 2025, 8:20am UTC](https://discourse.julialang.org/t/plot-recipes-with-nested-subplots/130465/1 "2025-07-04T08:20:08Z")

</div>

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:

```julia
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:

 ![desired_plot](https://global.discourse-cdn.com/julialang/original/3X/9/b/9b3f9a976b440d92f3edb679abaf7d2596f2a5ae.png)

I can get pretty close with nested `plot`s, but I have two problems:

1. This requires my package to have a dependency on `Plots`, which I would like to avoid.
2. This method also causes the legend to contain duplicate labels, one for each individual subplot.

This is my attempt with `Plots`:

```julia
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.

```julia
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?
