Subplotting incoherent behaviour

Hello,
I’m experiencing the following behavior, which confuses me a lot.

First of all, let’s consider the following code:

using Plots
x = range(0, 10, length=100)
y1 = @. exp(-0.1x) * cos(4x)
y2 = @. exp(-0.3x) * cos(4x)
y3 = @. exp(-0.1x)
y4 = @. exp(-0.3x)
y = [y1 y2 y3 y4]

p1 = plot(x, y)
p2 = plot(x, y, title="Title 2", lw=3)
p3 = scatter(x, y, ms=2, ma=0.5, xlabel="xlabel 3")
p4 = scatter(x, y, title="Title 4", ms=2, ma=0.2)
pp = [p1,p2,p3,p4]
plot(pp..., layout=(2,2), legend=false)

In this case I put all plots in a vector and splat them into plot, it is not very smart but it works.

In the following I do the same except that I append each subplot to pp instead of constructing it at the end

using Plots
x = range(0, 10, length=100)
y1 = @. exp(-0.1x) * cos(4x)
y2 = @. exp(-0.3x) * cos(4x)
y3 = @. exp(-0.1x)
y4 = @. exp(-0.3x)
y = [y1 y2 y3 y4]

pp = []
p1 = plot(x, y)
append!(pp,p1)
p2 = plot(x, y, title="Title 2", lw=3)
append!(pp,p2)
p3 = scatter(x, y, ms=2, ma=0.5, xlabel="xlabel 3")
append!(pp,p3)
p4 = scatter(x, y, title="Title 4", ms=2, ma=0.2)
append!(pp,p4)
plot(pp..., layout=(2,2), legend=false)

Here I get the error

julia> show(err)
1-element ExceptionStack:
LoadError: Couldn't process recipe args: (Plots.PlaceHolder, Plots.PlaceHolder, Plots.Subplot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend})
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] macro expansion
    @ ~/.julia/packages/RecipesPipeline/BGM3l/src/user_recipe.jl:158 [inlined]
  [3] apply_recipe(plotattributes::AbstractDict{Symbol, Any}, v1::Any, v2::Any, v3::Any, v4::Any, vrest::Any)
    @ RecipesPipeline ~/.julia/packages/RecipesBase/BRe07/src/RecipesBase.jl:300
  [4] _process_userrecipes!(plt::Any, plotattributes::Any, args::Any)
    @ RecipesPipeline ~/.julia/packages/RecipesPipeline/BGM3l/src/user_recipe.jl:38
  [5] recipe_pipeline!(plt::Any, plotattributes::Any, args::Any)
    @ RecipesPipeline ~/.julia/packages/RecipesPipeline/BGM3l/src/RecipesPipeline.jl:72
  [6] _plot!(plt::Plots.Plot, plotattributes::Any, args::Any)
    @ Plots ~/.julia/packages/Plots/du2dt/src/plot.jl:223
  [7] plot!(::Plots.Plot, ::Any, ::Vararg{Any}; kw...)
    @ Plots ~/.julia/packages/Plots/du2dt/src/plot.jl:213
  [8] plot(::Plots.Plot{Plots.GRBackend}, ::Plots.PlaceHolder, ::Vararg{Any}; kw::@Kwargs{layout::Tuple{Int64, Int64}, legend::Bool})
    @ Plots ~/.julia/packages/Plots/du2dt/src/plot.jl:206
  [9] plot(::Plots.Subplot, ::Any, ::Vararg{Any}; kw...)
    @ Plots ~/.julia/packages/Plots/du2dt/src/plot.jl:293
 [10] top-level scope
    @ ~/UNI/SLT/mini_project_2020/prova.jl:18
 [11] include(fname::String)
    @ Base.MainInclude ./client.jl:489
 [12] top-level scope
    @ REPL[7]:1
in expression starting at /home/ape/UNI/SLT/mini_project_2020/prova.jl:18


What’s the problem?

Julia Version 1.10.4 (2024-06-04)
Plots Version 1.40.5

Hello.
I think you should use push!() instead of append!().

The reason is this one.

2 Likes

That worked. It was an easy fix but I wouldn’t have found the solution by myself in a 1000 years. Thanks a lot.

You’re welcome.
The example in the SO post by @fredrikekre linked above, seems clearer than what is provided in the official docs.