# Plot! inside a function

So, to keep things on a plot (like Matlab’s “hold on”), you call plot as plot!(…).

If I make a function such as
function plotsomething(input)
intermediate result = do something with input
plot(intermediate result)
end

Is there an easy way to call plotsomething!() instead of plotsomething() and have it apply the “hold on” properties to the plot I used in the function?

There are two things I can think of, maybe one of them can fit your needs. The first is to write some separate function `f(input) = # do something with input`, and then you can have

``````function plotsomething(input)
intermediate_result = f(input)
plot(intermediate_result)
end
``````

and

``````function plotsomething!(input)
intermediate_result = f(input)
plot!(intermediate_result)
end
``````

(the definition of `f` is just to save on lines of code). The other possibility is something like

``````function plotsomething(input, hold_on = true)
intermediate_result = f(input)
if hold_on
plot!(intermediate_result)
else
plot(intermediate_result)
end
``````

You can also elect to make an empty plot with `plt = plot()` ahead of time and pass it into the function `plotsomething`, and then add what you want from the function with `plot(plt, ...)` where the ellipses indicate what you would put in `plot!` if you were simply adding to the last edited plot.

Hope something here helps!

``````using Plots

function plotsomething!(p, input; args...)
y = input .^ 2
plot!(p, input, y; args...)
end

p = plot()
plotsomething!(p, -5:5)
plotsomething!(p, -7:2; ls=:dash)
plotsomething!(p, [-2,2]; ms=8, st=:scatter)
``````
2 Likes

You could also use a callback:

``````using Plots

function plotsomething(input; pf = Plots.plot, args...)
y = input .^ 2
pf(input, y; args...)
end

plotsomething(-5:5)
plotsomething( -7:2; pf = plot!, ls=:dash)
``````
3 Likes

Hi Simon, does the callback solution allow handling independently different plot objects p1, p2, … ?

I get the following error:

``````p2 = plotsomething([-10,2]; ms=8, st=:scatter)
plotsomething([2,2]; pf=p2, ms=8, st=:scatter)

ERROR: MethodError: objects of type Plots.Plot{Plots.GRBackend} are not callable
``````

You could do it loke this:

``````using Plots

function plotsomething(input, p = nothing; pf = Plots.plot, kwargs...)
y = input .^ 2
if p === nothing
pf(input, y; kwargs...)
else
pf(p, input, y; kwargs...)
end
end

p1 = plotsomething(-5:5)
p2 = plotsomething(-7:7)
plotsomething( -7:2, p1; pf = plot!, ls=:dash)
``````

Or create a one and a two argument method.

1 Like

Thank you everyone for the responses. They really helped get a sense of what all of the options are.