Dispatch with @userplot and external recipes

Hi all,
I’m trying to learn the Plots.jl recipe syntax and have a few design questions.

Say I have

struct MyData{T} where {T<:Union{One,Two}}
   ...
end

I’d like to define @userplot PlotCustom for this, and provide two different plot types depending on the types One and Two.

julia> typeof(data)
MyData{One}
julia> plotcustom(data) # Produce a scatter plot
julia> typeof(data)
MyData{Two}
julia> plotcustom(data) # Produce a graphplot

Question 1: can/should I try to dispatch my recipe to two different methods, or is it fine to just put some if statement in the recipe and return different plots?
For example:

data = h.args[1]
if data.plot_type isa One
    seriestype := :scatter
    ...
else
    seriestype := :graphplot
    ...
end

The issue I have with this is that I’d like to provide some defaults with the methods and they need to be different. So multiple dispatch would be better here, but I’m not sure how to correctly return the applied properties (e.g. x := data.x) from such a function call.

Question 2. How can I pass my properties to another recipe? My Two type here needs to be plotted via graphplot, so I cannot just provide seriestype := :graphplot,

OK, so I’ve solved this myself I think.

Part 1: rather than use @userplot I just made the functions that would have been generated by the macro manually, but made them dispatchable:

mutable struct PlotCustom{AbstractType}
    args::Any                                      
end
    
plotcustom(args...; kw...) = RecipesBase.plot(PlotCustom{typeof(args[1].count)}(args); kw...)
#etc

Part 2: So long as I’m using GraphRecipes, I can omit assigning a value to seriestype, and leave the last line of my recipe as an <: AbstractGraph. Then the graph recipe will take over from there.

If anyone has a cleaner way of doing this I’d be interested to know!

3 Likes