Recipes distinguishing plot! from plot, for Plots.jl


#1

As the title says, is there a way for a recipe to distinguish whether it was called from plot!() rather than plot()?

For a trivial example, suppose p = plot(x::MyType) works out limits for axes, and normalises somehow, and that I want plot!(y) to add a few data points onto that, without changing axis scales, and re-using the same normalisation. Which I’d be happy to save as a global state somewhere, although if it were passed along as plot!(p, y) that would be nicer.

I believe what I have is called a “type recipe”. And that “user recipes” define new function myplot(x), which automatically comes with a related myplot!(x) cousin, so won’t let me do this.


#2

Distinguishing plot and plot! directly is not possible. One option is to pass around a state like so:

using Plots
using RecipesBase

struct MyType 
    xs::Vector{Float64}
    ys::Vector{Float64}
end
mutable struct MyState 
    state::Int
end
MyState(t::MyType) = MyState(0)

@recipe function plot(s::MyState, t::MyType)
    # some complicated logic that fiddles with the state
    s.state += 1
    label --> string(s)
    t.xs, t.ys
end

t = MyType(randn(10),randn(10))
s = MyState(t)
t2 = MyType(randn(10), randn(10))
plot(s,t)
scatter!(s, t2)