Makie Scatter Plot recipe for vector of custom types

This should be easy. At least it was for plots. I don’t understand what I am doing wrong. Looking for a simple example that shows me how to use convert_arguments. I think the documentation makes too many assumptions that you understand all of the in’s and out’s of Julia syntax. The recipe examples really needs work. It totally skips the easiest of examples and jumps right into the hard stuff.

For example, I have:

abstract type AbstractVec end

struct xyVecT{T<:Real} <: AbstractVec 
	x::T
	y::T
end

And I want to send a vector of those to a Makie.scatter command.
I want this to work:

v=[xyVecT{Float32}(x,y) for x=1:5 for y=2:4 ]
scatter(v)

What should convert_arguments look like, because I’ve tried about 30 different things now and still can’t figure it out. It seems like it should be easy and not take me 3 or 4 convert_arugment functions to do, but I think I keep chasing my tail.

If I have no convert_arguments defined for my custom type, I get the error:

ERROR: LoadError: Makie.convert_arguments for the plot type MakieCore.Scatter{Tuple{Vector{xyzVector.xyVecT{Float32}}}} and its conversion trait MakieCore.PointBased() was unsuccessful.

The signature that could not be converted was:
::Vector{xyzVector.xyVecT{Float32}}

This works but I couldn’t check if it is the best way to do it:

using GLMakie

abstract type AbstractVec end

struct xyVecT{T<:Real} <: AbstractVec
       x::T
       y::T
end

v=[xyVecT{Float32}(x,y) for x=1:5 for y=2:4 ]

function Makie.convert_arguments(P :: Type{<:Scatter}, v :: AbstractVector{<:xyVecT})  
    Makie.convert_arguments(P, [Point2f(elem.x,elem.y) for elem in v])
end

scatter(v)

Ha @Argel_Ramirez_Reyes was a bit faster, I guess I would do it like this, but I’m also not the authority in this area to be honest:

abstract type AbstractVec end

struct xyVecT{T<:Real} <: AbstractVec 
	x::T
	y::T
end

v=[xyVecT{Float32}(x,y) for x=1:5 for y=2:4]

function Makie.convert_arguments(::PointBased, v::AbstractVector{<:xyVecT})
    vec = [Point2f(vv.x, vv.y) for vv in v]
    (vec,)
end

scatter(v)
1 Like

Ah yes, I like this one better because it could work also for lines.
Is there a way for defining only the conversion for one element and having Makie automatically know what to do when given a vector of elements of a type it already know how to handle?

Makie doesn’t have any converts defined for container types irrespective of element type. I also don’t know what would make sense there. But you can define such element-container conversion method pairs yourself if it makes sense. One conversion for the element, one for the container that dispatches to the method for the element.

1 Like

Thanks I got it working.