# Is it possible to define a type-stable function that returns a Plots.Plot object?

**URL:** https://discourse.julialang.org/t/is-it-possible-to-define-a-type-stable-function-that-returns-a-plots-plot-object/112172
**Category:** Performance
**Tags:** plots
**Created:** [March 27, 2024, 9:05am UTC](https://discourse.julialang.org/t/is-it-possible-to-define-a-type-stable-function-that-returns-a-plots-plot-object/112172 "2024-03-27T09:05:16Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Shayan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shayan/32/33025_2.png) [@Shayan](https://discourse.julialang.org/u/Shayan)
#### Post date: [March 27, 2024, 9:05am UTC](https://discourse.julialang.org/t/is-it-possible-to-define-a-type-stable-function-that-returns-a-plots-plot-object/112172/1 "2024-03-27T09:05:17Z")

</div>

Is it possible to define a type stable function that returns a `Plots.plot` object?  
Minimal reproducible example:

```julia
using Plots
function mplot(vec::AbstractVector)
  plot(vec)
end

@code_warntype mplot(rand(10))

```

returns

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/e/def7279ce100f167edc6587cf65a8a4e36589195.png)

* * *

P.S.: I know the following is possible. I’m curious about another coding style

```julia
function mplot!(plt, vec::AbstractVector)
  plot!(plt, vec)
end
a = plot()
@code_warntype mplot!(a, rand(10))

```

returns

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

---

<div class="post-metadata">

### Author: ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)
#### Post date: [March 27, 2024, 9:39am UTC](https://discourse.julialang.org/t/is-it-possible-to-define-a-type-stable-function-that-returns-a-plots-plot-object/112172/2 "2024-03-27T09:39:49Z")

</div>

Without knowing anything about the internals of Plots.jl it looks like the `plot` function is inherently type-unstable (it returns a `Plots.Plot`, but without specifying the type parameter parameter/backend, it cannot be inferred to be a specific `Plots.Plot{SomeBackend}`).

I am only aware of setting the plot backend via functions (`gr()`, etc.), but maybe there are some ways to force `plot` to be more inferrable?

(If you just want to make your function type stable in the sense that the output type can be inferred “from the outside”, you could add a type assertion and hard-code the backend

```julia-repl
julia> function mplot2(vec::AbstractVector)
         plot(vec)::Plots.Plot{Plots.GRBackend}
       end
mplot2 (generic function with 1 method)

julia> @code_warntype mplot2(rand(10))
MethodInstance for mplot2(::Vector{Float64})
  from mplot2(vec::AbstractVector) @ Main REPL[27]:1
Arguments
  #self#::Core.Const(mplot2)
  vec::Vector{Float64}
Body::Plots.Plot{Plots.GRBackend}
1 ─ %1 = Main.plot(vec)::Plots.Plot
│ %2 = Plots.Plot::Core.Const(Plots.Plot)
│ %3 = Plots.GRBackend::Core.Const(Plots.GRBackend)
│ %4 = Core.apply_type(%2, %3)::Core.Const(Plots.Plot{Plots.GRBackend})
│ %5 = Core.typeassert(%1, %4)::Plots.Plot{Plots.GRBackend}
└── return %5

```

)

---

<div class="post-metadata">

### Author: ![Shayan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shayan/32/33025_2.png) [@Shayan](https://discourse.julialang.org/u/Shayan)
#### Post date: [March 27, 2024, 9:45am UTC](https://discourse.julialang.org/t/is-it-possible-to-define-a-type-stable-function-that-returns-a-plots-plot-object/112172/3 "2024-03-27T09:45:48Z")

</div>

> [@Sevi](#):
>
> `plot(vec)::Plots.Plot{Plots.GRBackend}`

This is a good solution in this case, but it isn’t enough in some cases like:

```julia
function mplot(vec::AbstractVector)
  p::Plots.Plot{Plots.GRBackend} = plot(vec)
  plot!(p, legend=true)
end

# Or

function mplot(vec::AbstractVector)
  p::Plots.Plot{Plots.GRBackend} = plot(vec)
  plot!(p, legend=true)::Plots.Plot{Plots.GRBackend}
end

# Or

function mplot(vec::AbstractVector)
  plot(vec)
  plot!(plegend=true)::Plots.Plot{Plots.GRBackend}
end

```

---

<div class="post-metadata">

### Author: ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)
#### Post date: [March 27, 2024, 1:24pm UTC](https://discourse.julialang.org/t/is-it-possible-to-define-a-type-stable-function-that-returns-a-plots-plot-object/112172/4 "2024-03-27T13:24:54Z")

</div>

> [@Shayan](#):
>
> This is a good solution in this case, but it isn’t enough in some cases like:

Could you elaborate please? `@code_warntype` reports essentially the same behavior for me in all three cases (the initial `Plots.Plot` object is marked red, but the overall return type of the function is known), so I’m not sure how these cases differ from the original.

Another option might be to use the underlying plotting backend directly, e.g. don’t use Plots.jl, but rather GR.jl since you have to specify the backend anyway, as it seems like (unless you add the backend as an input to the function of course).
