I'd like to (somehow) generate methods that dispatch when a function is called with one vector argument, starting from a "template".
My particular use case is plotting. I have a function that plots the behavior of a system defined by several scalar parameters, like this:
function myplot(a::Number, b::Number, c::Number)
results = calculate(a, b, c)
plot(results; xlabel="X Label", ylabel="Y Label", label="Signal")
end
I want to extend this method to explore how changing one parameter (a, b, or c) affects the behavior of this system.
The built-in vectorization with dot-calls (i.e., my plot.([a1 a2 a3], b, c) produces multiple plots. However, I would like to draw these as subplots within a single figure instead, while tweaking some subplot parameters to make it pretty. This is trivial to do for one parameter, like a:
function myplot(as::AbstractVecOrMat{T}, b::Number, c::Number) where T <: Number
plots = []
for (ix, a) in enumerate(as)
results = calculate(a, b, c)
push!(plots, plot(results;
label=ix==1 ? "Signal" : nothing,
xlabel=ix==length(as) ? "X Label" : "")
end
plot(plots...; layout=grid(length(plots), 1), plot_title="Effects of varying a")
end
What is the best way to create similar functions for visualizing changes in b or c? These would be identical, except for a) the signature, b) the loop variable, and c) the plot_title. Copy-and-paste is one obvious option, but feels inelegant. Another option would be to make the vectorized version take only vectors. However, it is slightly annoying to provide [x] instead of x, and this visualization can be misleading if multiple parameters vary at the same time.
It feels like there must be an elegant metaprogramming/macro solution, but I can't quite figure it out.