Repository: JuliaPlots/Makie.jl (julia)

Issue:
Add hint to f, ax, p=plot(x) to the FigureAxisPlot plot! error message
As described on slack https://julialang.slack.com/archives/C8RQUU2KH/p1706888052109789
When trying to simply plot two things after another we get an error because we can't plot into a FigureAxisPlot as seen below. 
This is confusing for new users and there should be a hint to the Makie pattern of using `fig, ax, p = plot(x)` to then plot into the `ax`.

```julia
julia> plt = plot(x)

julia> plot!(plt, y)
ERROR: PlotMethodError: no plot method for arguments (::Makie.FigureAxisPlot, ::Vector{Float32}). To support these arguments, define
  plot!(::Combined{Any, S} where S<:Tuple{Makie.FigureAxisPlot, Vector{Float32}})
Available methods are:
```

Pull request description:
Fixes #3593 

Example:

```julia
julia> p = lines(1:10)
       lines!(p, 1:20)
ERROR: ArgumentError: Tried plotting with `lines!` into a `FigureAxisPlot` object, this is not allowed.

The `FigureAxisPlot` object is returned by plotting functions not ending in `!` like `lines(...)` or `scatter(...)`.

It contains the new `Figure`, the new axis object, for example an `Axis`, `LScene` or `Axis3`, and the new plot object. It exists just as a convenience because returning it displays the contained figure. For all further operations, you should split it into its parts instead. This way, it is clear which of its components you are targeting.

You can do this with the destructuring syntax `fig, ax, plt = some_plot(...)` and then continue, for example with `lines!(ax, ...)`.

Stacktrace:
 [1] _create_plot!(::Function, ::Dict{Symbol, Any}, ::Makie.FigureAxisPlot, ::UnitRange{Int64})
   @ Makie ~/.julia/dev/Makie/src/figureplotting.jl:257
 [2] lines!(::Makie.FigureAxisPlot, ::Vararg{Any}; kw::@Kwargs{})
   @ MakieCore ~/.julia/dev/Makie/MakieCore/src/recipes.jl:176
 [3] top-level scope
   @ REPL[20]:2
```

Patch:
diff --git a/src/figureplotting.jl b/src/figureplotting.jl
index 4abfc12e42c..a1c5f53d2ca 100644
--- a/src/figureplotting.jl
+++ b/src/figureplotting.jl
@@ -252,6 +252,31 @@ default_plot_func(::typeof(plot), args) = plotfunc(plottype(map(to_value, args).
 end
 
 @noinline function MakieCore._create_plot!(F, attributes::Dict, args...)
+    if length(args) > 0
+        if args[1] isa FigureAxisPlot
+            throw(ArgumentError("""
+            Tried plotting with `$(F)!` into a `FigureAxisPlot` object, this is not allowed.
+
+            The `FigureAxisPlot` object is returned by plotting functions not ending in `!` like `lines(...)` or `scatter(...)`.
+            
+            It contains the new `Figure`, the new axis object, for example an `Axis`, `LScene` or `Axis3`, and the new plot object. It exists just as a convenience because returning it displays the contained figure. For all further operations, you should split it into its parts instead. This way, it is clear which of its components you are targeting.
+            
+            You can do this with the destructuring syntax `fig, ax, plt = some_plot(...)` and then continue, for example with `$(F)!(ax, ...)`.
+            """))
+        end
+        if args[1] isa AxisPlot
+            throw(ArgumentError("""
+            Tried plotting with `$(F)!` into a `AxisPlot` object, this is not allowed.
+
+            The `AxisPlot` object is returned by plotting functions not ending in `!` with
+            a `GridPosition` as the first argument, like `lines(fig[1, 2], ...)` or `scatter(fig[1, 2], ...)`.
+            
+            It contains the new axis object, for example an `Axis`, `LScene` or `Axis3`, and the new plot object. For all further operations, you should split it into its parts instead. This way, it is clear which of its components you are targeting.
+            
+            You can do this with the destructuring syntax `ax, plt = some_plot(fig[1, 2], ...)` and then continue, for example with `$(F)!(ax, ...)`.
+            """))
+        end
+    end
     figarg, pargs = plot_args(args...)
     figkws = fig_keywords!(attributes)
     plot = Plot{default_plot_func(F, pargs)}(pargs, attributes)


Test patch:
diff --git a/test/figures.jl b/test/figures.jl
index f9018b8b39f..d6968de4aba 100644
--- a/test/figures.jl
+++ b/test/figures.jl
@@ -17,6 +17,7 @@ end
     @test fig isa Figure
     @test ax isa Axis
     @test p isa Scatter
+    @test_throws ArgumentError lines!(fap, 1:10)
 
     fig2, ax2, p2 = scatter(rand(100, 3))
     @test fig2 isa Figure
@@ -34,6 +35,7 @@ end
     ap = scatter(gridpos, rand(100, 2))
     @test ap isa Makie.AxisPlot
     @test current_axis() === ap.axis
+    @test_throws ArgumentError lines!(ap, 1:10)
 
     ax2, p2 = scatter(fig[1, 2], rand(100, 2))
     @test ax2 isa Axis