# Trouble understanding how plot recipes dispatches customized types containing other customized types

**URL:** <https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357>\
**Category:** New to Julia\
**Tags:** question, plotting, recipe\
**Created:** [May 1, 2021, 4:11am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357 "2021-05-01T04:11:15Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [May 1, 2021, 4:11am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/1 "2021-05-01T04:11:15Z")

</div>

Can someone explain why the following doesn’t work?

```julia
julia> using RecipesBase

julia> struct Pair
           x::Vector{Float64}
           y::Vector{Float64}
       end

julia> struct Pairs
           pairs::Vector{Pair}
       end

julia> @recipe function plot(pair::Pair)
           pair.x, pair.y
       end

julia> @recipe plot(pairs::Pairs) = pairs.pairs

julia> N = 10
10

julia> pvec = [Pair(rand(N), rand(N)) for m = 1:15];

julia> pairs = Pairs(pvec);

julia> using Plots

julia> plot(pairs.pairs[1])

```

![Screenshot (1)](https://global.discourse-cdn.com/julialang/original/3X/d/4/d4b17a0a5ad25a05bc88608a411383e6fed3c03d.png)

```julia
julia> plot(pairs)
ERROR: Cannot convert Pair to series data for plotting

```

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [May 1, 2021, 5:21am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/2 "2021-05-01T05:21:16Z")

</div>

Two things: `Pair` is defined in Base, (`:a => 2` is a `Pair{Symbol, Int64}`). And Type recipes need a type argument as well:

```julia
@recipe f(::Type{MyPair}, x::MyPair) = x.x, x.y

```

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [May 5, 2021, 2:24am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/3 "2021-05-05T02:24:41Z")

</div>

> [@gustaphe](#):
>
> `Pair` is defined in Base

Ah, didn’t know that when I built this MWE. Thanks.

> [@gustaphe](#):
>
> Type recipes need a type argument as well

Oh that’s right, I did see that they’re kind of inputted twice in the recipe signature, but I’m still confused as to why. I’ve been reading the [Recipes documentation](https://docs.juliaplots.org/latest/recipes/) over and over, and a lot of it keeps going over my head.

Thanks!

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [May 5, 2021, 2:40am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/4 "2021-05-05T02:40:26Z")

</div>

I’m not so sure I did it right.

 ![2021-05-05](https://global.discourse-cdn.com/julialang/original/3X/a/1/a1889a3c230bea28fc65de0405e5d6cf98d660f7.png)

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [May 5, 2021, 5:50am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/5 "2021-05-05T05:50:14Z")

</div>

Yeah, it’s not entirely intuitive. If your recipe signature is `(::Type{MyType}, ::MyType)` then it’s a _type recipe_, and will mesh in with everything. Essentially “Hey Plots, if you see a `MyType` anywhere, do this”. If the signature is `(::MyType)` that’s a _user recipe_, and will only work for `plot` calls with that exact signature. I’m not 100% sure, but I don’t think that recipes in turn invoke user recipes, for instance.

I’m not entirely sure what’s going wrong here, but notice the `x` axis in your graph. Turns out we’re plotting the `x` vector against its indices.

I haven’t worked with a `Vector{Vector}` type before, maybe you actually have to resort to user recipes to get this working. One thing that works is turning it into a `Vector{Tuple{Float64, Float64}}`: `@recipe f(::Type{MyPair}, mp::MyPair) = collect(zip(mp.x, m.y))`.

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [November 1, 2021, 8:22am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/6 "2021-11-01T08:22:13Z")

</div>

Thanks @gustaphe.

This works fine for `plot(mypair)` where `mypair isa MyPair`, but `plot(mypairs)` where `mypairs isa MyPairs` still doesn’t work.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [November 1, 2021, 8:41am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/7 "2021-11-01T08:41:29Z")

</div>

A couple of questions:

- Exactly what code are you running?
- If `MyPair` is essentially a `(x::Vector{Float64}, y::Vector{Float64})` type, then `MyPairs` is basically a vector of pairs of vectors. What do you expect plotting that to look like?
- What do you mean by “doesn’t work”?

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [November 1, 2021, 9:05am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/8 "2021-11-01T09:05:45Z")

</div>

Having returned to this problem, I cringe at how I expressed my question haha. Thanks for asking.

Basically, suppose I have

```julia
struct Path
  x::Vector{Int}
  y::Vector{Int}
end

```

and I define a plot recipe for it

```julia
using RecipesBase
@recipe f(::Type{Path}, p::Path) = collect(zip(p.x, p.y))

```

which works fine

```julia
using Plots
path = Path(1:10, rand(1:10, 10))
plot(path)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/4/b46cf2e5e0cdddf109e3a828f9e32c81619ec1a8.png)

But I want to manage a collection of `path`s. So I define

```julia
struct Paths
	xy::Vector{Path}
end

```

and instantiate,

```julia
paths = Paths([Path(1:10, rand(1:10, 10)) for n = 1:3])

```

and now need a plot recipe so that `plot(paths)` “just works,” i.e. it plots all the `Path`s in the same axes, like so,

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/f/1ff70a424b06897918f164a6444e3a75d3eb3d01.png)  
which was produced with

```julia
plot()
for p in paths.xy
	plot!(p)
end
plot!()

```

which is of course unpreferable.

What doesn’t work is:

```julia
@recipe f(::Type{Paths}, p::Paths) = p.xy
plot(paths)

```

which produces: `Error: Cannot convert Path to series data for plotting`.

I’ve read the documentation here and here over ten times through already, and each time I re-read I learn something new but nothing to answer this question. And no existing discussions online ask nor provide an answer to this question.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [November 1, 2021, 9:28am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/9 "2021-11-01T09:28:40Z")

</div>

Like I mentioned before, this is not intuitive for me either, and I think I’ve written my share of recipes.

```julia
plot([[Tuple(rand(2)) for _ in 1:10] for _ in 1:3])

```

(i.e. `plot(::Vector{Vector{Tuple}})`) doesn’t work either, so even if your recipe did work properly, it would fail.

I’m not sure if a type recipe is even the right thing here, you will probably never plot a `Paths` _against_ something else. So maybe a user recipe is enough:

```julia
@recipe function f(paths::Paths)
    for path in paths.xy
        @series begin
            path
        end
    end
end

```

(maybe needlessly verbose, but I can’t think of a good shorter way)

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [November 1, 2021, 9:33am UTC](https://discourse.julialang.org/t/trouble-understanding-how-plot-recipes-dispatches-customized-types-containing-other-customized-types/60357/10 "2021-11-01T09:33:33Z")

</div>

That does seem like the best option. Or better said, the only option that actually produces something, I’ll accept it thanks!
