# Plotting 2 functions

**URL:** <https://discourse.julialang.org/t/plotting-2-functions/28348>\
**Category:** General Usage\
**Tags:** plotting\
**Created:** [September 3, 2019, 8:37pm UTC](https://discourse.julialang.org/t/plotting-2-functions/28348 "2019-09-03T20:37:13Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thalorn](https://avatars.discourse-cdn.com/v4/letter/t/46a35a/32.png) [@Thalorn](https://discourse.julialang.org/u/Thalorn)\
**Post date:** [September 3, 2019, 8:37pm UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/1 "2019-09-03T20:37:13Z")

</div>

Hi, Im trying to plot my Chebyshev approximation

```julia
using Printf
using Plots
pyplot()

mutable struct Cheb_struct
    c::Vector{Float64}
    min::Float64
    max::Float64
end

function cheb_coeff(min::Float64, max::Float64, n::Int, fn::Function)::Cheb_struct
    struc = Cheb_struct(Vector{Float64}(undef,n), min, max)
    f = Vector{Float64}(undef,n)
    p = Vector{Float64}(undef,n)
    max_plus_min = (max + min) / 2
    max_minus_min = (max - min) / 2
    for k in 0:n-1
        p[k+1] = pi * ((k+1) - 0.5) / n
        f[k+1] = fn(max_plus_min + cos(p[k+1])*max_minus_min)
    end
    n2 = 2 / n
    for j in 0:n-1
        s = 0
        for i in 0:n-1
            s += f[i+1]*cos(j*p[i+1])
        struc.c[j+1] = s * n2
    end
end
    return struc
end

function approximate(struc::Cheb_struct, x::Float64)::Float64
    x1 = (2*x - struc.max - struc.min) / (struc.max - struc.min)
    x2 = 2*x1
    t = s = 0
    for j in length(struc.c):-1:2
        pom = s
        s = x2 * s - t + struc.c[j]
        t = pom
    end
    return (x1 * s - t + struc.c[1] / 2)
end

fn = sin
struc = cheb_coeff(0.0, 1.0, 10, fn)
println("coeff:")

for i in struc.c
    @printf("% .15f\n", i)
end

println("\n x eval approx eval-approx")
for x in struc.min:0.1:struc.max
    ev= fn(x)
    approx= approximate(struc, x)
    @printf("%12.8f %12.8f %12.8f % .3e\n", x,ev, approx, ev-approx)
    p =plot(ev,approx)
    display(p)
end

```

But I´m getting error:

```julia
ERROR: LoadError: Cannot convert Float64 to series data for plotting
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] prepareSeriesData(::Float64) at C:\Users\wunsc\.julia\packages\Plots\Ih71u\src\series.jl:13
 [3] convertToAnyVector(::Float64) at C:\Users\wunsc\.julia\packages\Plots\Ih71u\src\series.jl:24
 [4] macro expansion at C:\Users\wunsc\.julia\packages\Plots\Ih71u\src\series.jl:113 [inlined]
 [5] apply_recipe(::Dict{Symbol,Any}, ::Type{Plots.SliceIt}, ::Float64, ::Float64, ::Nothing) at C:\Users\wunsc\.julia\packages\RecipesBase\zBoFG\src\RecipesBase.jl:275
 [6] _process_userrecipes(::Plots.Plot{Plots.PyPlotBackend}, ::Dict{Symbol,Any}, ::Tuple{Float64,Float64}) at C:\Users\wunsc\.julia\packages\Plots\Ih71u\src\pipeline.jl:83
 [7] _plot!(::Plots.Plot{Plots.PyPlotBackend}, ::Dict{Symbol,Any}, ::Tuple{Float64,Float64}) at C:\Users\wunsc\.julia\packages\Plots\Ih71u\src\plot.jl:178
 [8] #plot#133(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(plot), ::Float64, ::Vararg{Float64,N} where N) at C:\Users\wunsc\.julia\packages\Plots\Ih71u\src\plot.jl:57
 [9] plot(::Float64, ::Float64) at C:\Users\wunsc\.julia\packages\Plots\Ih71u\src\plot.jl:51
 [10] top-level scope at C:\Users\wunsc\Desktop\Julia\test.jl:57
 [11] include at .\boot.jl:328 [inlined]
 [12] include_relative(::Module, ::String) at .\loading.jl:1094
 [13] include(::Module, ::String) at .\Base.jl:31
 [14] include(::String) at .\client.jl:431
 [15] top-level scope at REPL[2]:1
in expression starting at C:\Users\wunsc\Desktop\Julia\test.jl:53

```

I would be very grateful if someone could help me to plot these two functions.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [September 4, 2019, 12:08am UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/2 "2019-09-04T00:08:41Z")

</div>

```julia
ev= fn(x)

```

this makes it a single number?..(as what the error msg is trying to tell you

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 4, 2019, 12:20am UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/3 "2019-09-04T00:20:30Z")

</div>

Probably you want something like:

```julia
x = struc.min:0.1:struc.max
plot(x, [fn.(x), approximate.(struc, x)])

```

to evaluate your `fn` and its approximation for an array of points and plot them both vs. `x`.

---

<div class="post-metadata">

**Author:** ![Thalorn](https://avatars.discourse-cdn.com/v4/letter/t/46a35a/32.png) [@Thalorn](https://discourse.julialang.org/u/Thalorn)\
**Post date:** [September 4, 2019, 7:51am UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/4 "2019-09-04T07:51:20Z")

</div>

I tried that but now Im getting

```julia
ERROR: LoadError: MethodError: no method matching length(::Cheb_struct)
Closest candidates are:
  length(::Core.SimpleVector) at essentials.jl:597
  length(::Base.MethodList) at reflection.jl:819
  length(::Core.MethodTable) at reflection.jl:893

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 4, 2019, 8:07am UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/5 "2019-09-04T08:07:28Z")

</div>

try

```julia
approximate.(Ref(struc), x)

```

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [September 4, 2019, 8:24am UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/6 "2019-09-04T08:24:07Z")

</div>

> [@stevengj](#):
>
> Probably you want something like:
> 
> ```julia
> x = struc.min:0.1:struc.max
> plot(x, [fn.(x), approximate.(struc, x)])
> 
> ```
> 
> to evaluate your `fn` and its approximation for an array of points and plot them both vs. `x` .

An alternative syntax in Plots is to pass the anonymous functions and extrema:

```julia
plot([fn, t -> approximate(struc, t)], struc.min, struc.max)

```

and Plots will figure out a good set of points to evaluate the function on. It’s mainly useful if the functions have some singular points where denser sampling is needed.

---

<div class="post-metadata">

**Author:** ![Thalorn](https://avatars.discourse-cdn.com/v4/letter/t/46a35a/32.png) [@Thalorn](https://discourse.julialang.org/u/Thalorn)\
**Post date:** [September 4, 2019, 8:31am UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/7 "2019-09-04T08:31:06Z")

</div>

Thank you very much, both of these approaches worked.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 4, 2019, 11:46am UTC](https://discourse.julialang.org/t/plotting-2-functions/28348/8 "2019-09-04T11:46:41Z")

</div>

Since I’m guessing you are doing this as a learning exercise (the [ApproxFun package](https://github.com/JuliaApproximation/ApproxFun.jl) already implements Chebyshev approximation in a much more complete way), let me give a few suggestions.

> [@Thalorn](#):
>
> `function approximate(struc::Cheb_struct, x::Float64)::Float64`

Note, by the way, that these type declarations don’t actually help you. It would be more flexible, and just as fast, to just use `function approximate(struc::Cheb_struct, x::Number)`. Whenever you call a function, Julia’s compiler specializes it for the given argument types and compiles a type-specialized version.

Similarlly for

```julia
function cheb_coeff(min::Float64, max::Float64, n::Int, fn::Function)::Cheb_struct

```

Overspecifying the argument types like this makes your function unnecessarily inflexible without making it any faster. A key strength of Julia is that you can write code that is simultaneously type-generic and fast.

(Since this is a constructor function, you would normally name it after the type. i.e. call the function `function Cheb_struct(...)`.)

I assume that you realize you are using an O(n^2) algorithm whereas it’s possible to construct the Chebyshev coefficients in O(n\log n) operations using FFTs. The [FFTW.jl package](https://github.com/JuliaMath/FFTW.jl) provides fast DCT routines that are suited to Chebyshev approximation.

> [@Thalorn](#):
>
> `t = s = 0`

This is a [type instability](https://docs.julialang.org/en/v1/manual/performance-tips/index.html#Avoid-changing-the-type-of-a-variable-1) and will hurt performance. Instead, use the type of `x2`:

```julia
t = s = zero(x2)

```

Note also that for this sort of thing you can make `Cheb_struct` callable instead:

```julia
function (struc::Cheb_struct)(x::Real)
    ...
end

```

Then you can just do `struc(x)` instead of `approximate(struc, x)`, and `struc.(x)` to operate on an array.

```julia
mutable struct Cheb_struct
    c::Vector{Float64}
    min::Float64
    max::Float64
end

```

As far as I can tell there is no need for this to be `mutable`. You can change the _elements_ of `c` even if the `struct` is not mutable, because a `Vector` is a mutable container. Also, in general for something like this I would recommend parameterizing the type, i.e.

```julia
struct Cheb{T<:AbstractFloat}
    c::Vector{T}
    min::T
    max::T
end

```

(omitting `_struct` from the name since `CamelCase` names in Julia typically denote types or modules.)
