# Plots.jl horizontal and vertical labels across subplots in grid layout

**URL:** <https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113>\
**Category:** Visualization\
**Tags:** plots, layout-plots\
**Created:** [April 27, 2021, 3:34pm UTC](https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113 "2021-04-27T15:34:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [April 27, 2021, 3:34pm UTC](https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113/1 "2021-04-27T15:34:23Z")

</div>

```julia
using Plots

n_from = 2
n_to = 3

froms = [Plots.fakedata(100) for i = 1:n_from]
tos = [Plots.fakedata(100) for i = 1:n_to]

gl = grid(n_from + 1 , n_to + 1)
p = plot(;layout = gl, aspect_ratio = 1.0)

# setup subplots
for gi in CartesianIndices(axes(gl))
    gi = Tuple(gi)
    _subplot = gl[gi...]
    if gi == (1, 1)
        # bug, clears all subplots
        #plot!(_subplot, legend = false, grid = false, foreground_color_subplot=:white)
        continue
    end
    plot!(_subplot, aspect_ratio = 1.0, framestyle = :origin, link = :square, ticks=nothing,)
end

# plot column header
for i = 1:n_from
    plot!(gl[1 + i, 1], froms[i], label="")
end

# plot row header
for j = 1:n_to
    plot!(gl[1, 1 + j], tos[j], label="")
end

# plot swept volumes
for i = 1:n_from, j = 1:n_to
    d = froms[i] .* tos[j]
    plot!(gl[1 + i, 1 + j], d, label="")
end

display(p)

```

produces  
 ![demo1](https://global.discourse-cdn.com/julialang/original/3X/4/3/4338f3535b5173c6613b69bd8d5503c5bc0e9876.png)

and I would like to do something that looks like the following mock-up

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/d/fdae4caaa89ef556505daf6ba652b1bc5228f4db.png)

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [April 27, 2021, 4:05pm UTC](https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113/2 "2021-04-27T16:05:27Z")

</div>

Using the idea of [julia - Adding global title to Plots.jl subplots - Stack Overflow](https://stackoverflow.com/a/58451530) to include a subplot that serves only to include a title, I tried:

```julia
# [...]
gl = grid(n_from + 1 , n_to + 1)

l = @layout [
    c b{0.1h};
    a{0.1w} gl
]

p = plot(;layout = l, aspect_ratio = 1.0)
# [...]

```

which gives

```julia
ERROR: LoadError: Cannot convert Plots.EmptyLayout to series data for plotting
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:33
  [2] _prepare_series_data(x::Plots.EmptyLayout)
    @ RecipesPipeline ~/.julia/packages/RecipesPipeline/CirY4/src/series.jl:8
  [3] _series_data_vector(x::Plots.EmptyLayout, plotattributes::Dict{Symbol, Any})
    @ RecipesPipeline ~/.julia/packages/RecipesPipeline/CirY4/src/series.jl:27
  [4] macro expansion
    @ ~/.julia/packages/RecipesPipeline/CirY4/src/series.jl:144 [inlined]
  [5] apply_recipe(plotattributes::AbstractDict{Symbol, Any}, #unused#::Type{RecipesPipeline.SliceIt}, x::Any, y::Any, z::Any)
    @ RecipesPipeline ~/.julia/packages/RecipesBase/92zOw/src/RecipesBase.jl:282
  [6] _process_userrecipes!(plt::Any, plotattributes::Any, args::Any)
    @ RecipesPipeline ~/.julia/packages/RecipesPipeline/CirY4/src/user_recipe.jl:36
  [7] recipe_pipeline!(plt::Any, plotattributes::Any, args::Any)
    @ RecipesPipeline ~/.julia/packages/RecipesPipeline/CirY4/src/RecipesPipeline.jl:70
  [8] _plot!(plt::Plots.Plot, plotattributes::Any, args::Any)
    @ Plots ~/.julia/packages/Plots/kyYZF/src/plot.jl:172
  [9] #plot!#149
    @ ~/.julia/packages/Plots/kyYZF/src/plot.jl:162 [inlined]
 [10] plot!(args::Any; kw::Any)
    @ Plots ~/.julia/packages/Plots/kyYZF/src/plot.jl:153

```

If I `display(p)` without trying to populate any of the plots, I get:

![image](https://global.discourse-cdn.com/julialang/original/3X/8/2/82661f343ed85a5333f476dd6c1a8576d8b289c1.png)

But that was due to my misunderstanding of the `@layout` macro, which does not resolve names like `gl`, but requires instead

```julia
# [...]
# gl = grid(n_from + 1 , n_to + 1)

l = @layout [
    c b{0.1h}
    a{0.1w} grid(n_from + 1 , n_to + 1)
]

gl = l[2, 2]
p = plot(;layout = l, aspect_ratio = 1.0);
# [...]

```

which gives

![image](https://global.discourse-cdn.com/julialang/original/3X/6/1/61e8bea4b6878b04d48bca58d921fd5bca3d8754.png)

which is sort-of the layout I need.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [April 27, 2021, 6:36pm UTC](https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113/3 "2021-04-27T18:36:21Z")

</div>

I know you asked about Plots, but it’s too enticing for me to try and solve layout problems in Makie… Sorry!

```julia
using CairoMakie

f = Figure()

for i in 1:3, j in 1:4
    if (i, j) != (1, 1)
        ax = Axis(f[i+1, j+1])
        hidedecorations!(ax)
        hidespines!(ax)
        hlines!(ax, 0)
        vlines!(ax, 0)
        lines!(ax, randn(200), color = :lightblue)
        ylims!(-5, 10)
    end
end

Label(f[1, 3:5], "Label across columns")
Label(f[3:4, 1], "Label across rows", rotation = pi/2)

f

```

 ![grafik](https://global.discourse-cdn.com/julialang/original/3X/a/1/a1e6d636be916717f25b0f0598f12861c0b44c97.png)

---

<div class="post-metadata">

**Author:** ![Wei\_Yang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wei_yang/32/23951_2.png) [@Wei\_Yang](https://discourse.julialang.org/u/Wei_Yang)\
**Post date:** [April 27, 2021, 7:14pm UTC](https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113/4 "2021-04-27T19:14:39Z")

</div>

😲Looks much easier to control than Plots, time to ditch Plots 😍

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [April 27, 2021, 7:20pm UTC](https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113/5 "2021-04-27T19:20:05Z")

</div>

Thanks, @jules! I would like to use Makie, but I’m nervous about not leveraging recipes written for RecipeBase.jl. Do you (or anyone) have any advice to offer about [MakieRecipes.jl](https://github.com/JuliaPlots/MakieRecipes.jl/issues/28)?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [April 27, 2021, 7:23pm UTC](https://discourse.julialang.org/t/plots-jl-horizontal-and-vertical-labels-across-subplots-in-grid-layout/60113/6 "2021-04-27T19:23:55Z")

</div>

We’re heavily thinking about the recipes aspect, our internal design is just not one to one compatible with the plots recipe system. So one question is, how much can we emulate that system to make use of existing recipes, and the other is can we design a system that is better suited to makie’s capabilities
