# Recipe to plot unit points

I am bring to define a Recipe for my own data type, but following any thread here (for example Understanding recipes in Plots.jl ) I always end up with `No user recipe defined for MyType` errors and I would like to understand, where my mistake is. I try to simplify my problem with a (n)MWE.

Let’s assume I have a data type to store unit norm vectors and would like to have a plot for the following `pts` vector of `uV`s

``````using RecipesBase, Plots

struct uV
value::Vector
end
pts = uV.([ [1., 0., 0.], [0., 1., 0.], [0., 0., -1.], 1/sqrt(3)*[1., 1., 1.] ])

@recipe f(::Type{uV}, x::uV) = x.value
plot(pts)
``````

which should resemble a type recipe from Recipes · Plots that what I think I should be aiming for? But nearly independent of what I tried I get the `No user recipe`, so maybe I don’t need a type recipe? That’s where I am confused.

What should the plot do?
First, just plot the points von `uV`as dots in R3 (if somebody could snuck a half transparent sphere in between, that would be really lovely). Later I would like to extend this to maybe even draw lines (or curves) between the points if they are given as an `NTuple` (instead of an array).

Your `pts` is like a `Vector{Vector}` which can not be plotted, try plotting `pts[1]` and it should work

2 Likes

Interesting. Yes that plots, but not what I want.

Maybe I am more into `scatter`ing my vector? As I described, I would like to draw a dot (or connect them with a line) for every entry of pts. That’s why I thought of a plot, basically it should

combine als first entries in x, all seconds in y all thirds in z and plot that (then getting points could be done using a marker?).

I am sorry if that’s confusing, but I really seem to miss the magic in the recipes for now.

Like so?

``````@recipe function f(x::AbstractVector{<:uV}) reduce(hcat, x.value for x in x)' end
plot(pts)
``````
1 Like

That’s a good starting point!

And then even `scatter(pts)` works. The `'`and `reduce` have to read carefully again, but I now see where my error was: I though with `DataType` the documentation referred to single data items, but actually a `@reciepe` transforms the input (so here the vector of data points) into something it can continue with.

Now I just have to find out why my plots then end up being 2D instead of 3D; but you already helped me a lot

1 Like

With that mixup gone, I managed to do the following

``````@recipe f(x::AbstractVector{<:uV}) = Tuple( reduce(hcat, x.value for x in x)[i,:] for i=1:3 )

scatter3d(pts)
``````

then beautifully scatters the `uV`s in the array `pts`. Might not be the most beautiful solution for the recipe, but one that works as intended.

Try this then, maybe a more efficient solution

``````Base.getindex(x::uV,i) = x.value[i]
Base.length(x::uV) = length(x.value)
@recipe f(x::AbstractVector{<:uV}) = ntuple(i->getindex.(x, i), length(x[1]))
scatter3d(pts)
``````
1 Like

That’s a beautiful solution. Thanks.

1 Like