Recipe to plot several line segments on the same graph

A custom type contains a vector of matrices. Each two-column matrix defines a continuous line segment.

To plot this type, a plot!() function needs to be called as many times as there are line segments.
I am not sure which macro from RecipesBase I need to use so as not to introduce the
dependency on Plots.

Would that be a “user recipe” where the @series macro is called in a loop?

Thanks.

julia> x = [ rand(2,2) for _ in 1:10 ];

julia> using Plots

julia> plot([(m[1,:],m[2,:]) for m in x])

gives:

image

something like that can work, probably.

An alternative would be to use:

plot(Tuple.(collect.(eachcol.(m.x))))

.
MWE:

struct mytype
    x::Vector{Matrix{Float64}}
end

using RecipesBase

@recipe function f(m::mytype)
    @series begin
        Tuple.(collect.(eachcol.(m.x)))
    end
end

m = mytype([[sort(rand(5)) rand(5)] for _ in 1:10])

using Plots
plot(m)
2 Likes

RecipesBase is a lightweight Package without dependencies that allows to define custom visualizations with the @recipe macro.

Package developers and users can define recipes to tell Plots.jl how to plot custom types without depending on it.

I clearly misunderstood what you where asking, sorry. No, I’m not used to defining new plot recipes.

Thank you. I didn’t realize that vector of tuples can plot() the disjointed line segments. Is it anywhere in Plots.jl documentation?

Plots.jl documentation could be more detailed when it comes to plot() function, I think:

There are lots of ways to pass in data, and lots of keyword arguments… just try it and it will likely work as expected.

Phew, thanks a bunch, API reference! That was really helpful.

I think you raise a very good point. The Plots.jl documentation could be greatly improved in the Input Data section.

I learn by poking around.
Maybe the following simple example could be added to the docs:

x1, x2 = [1, 0],  [2, 3]    # vectors
y1, y2 = [4, 5],  [6, 7]    # vectors
m1, m2 = [x1 y1], [x2 y2]   # matrices

plot([m1, m2])              # array of matrices -> 4 series, plots each matrix column, x assumed to be integer count
plot([[x1,y1], [x2,y2]])    # array of array of arrays -> 4 series, plots each individual array, x assumed to be integer count 
plot([(x1,y1), (x2,y2)])    # array of tuples of arrays -> 2 series, plots each tuple as new series

It probably should. At present, this method is undiscoverable except by reading code or trial and error. I tried a tuple of tuples and array of arrays, whereas the internet search only brought the suggestion to insert NaNs into a vector.

Fyi, suggested adding the last minimal example to Plots.jl documentation via this PR.

1 Like