# Simple interpolation?

**URL:** https://discourse.julialang.org/t/simple-interpolation/55320
**Category:** General Usage
**Tags:** interpolations
**Created:** [February 15, 2021, 2:10pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320 "2021-02-15T14:10:48Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 15, 2021, 2:10pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/1 "2021-02-15T14:10:48Z")

</div>

I could do with some maths help!

I have a few equally-spaced values between 0.0 and 1.0:

```julia
[0.0, 0.1, 0.85, 0.9, 1.0]

```

and I want a function `f(n)` that returns a suitably close value for any other `n` between 0.0 and 1.0. So a value of 0.5 would lie on some kind of line that meanders through all the known points.

I can draw it in 2D:

 ![Screenshot 2021-02-15 at 14.06.20](https://global.discourse-cdn.com/julialang/original/3X/2/8/28a1cb1bb1d41fd1d79cab5ff9183af54eec8e8d.png)

but I can’t work out how to code it…

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [February 15, 2021, 2:47pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/2 "2021-02-15T14:47:35Z")

</div>

Something like this?

```julia
julia> using Interpolations, Plots

julia> y = [0.0, 0.1, 0.85, 0.9, 1.0];

julia> x = range(0, stop = 1, length = 5);

julia> itp = interpolate((x,), y, Gridded(Linear()))
5-element interpolate((0.0:0.25:1.0,), ::Vector{Float64}, Gridded(Linear())) with element type Float64:
 0.0
 0.1
 0.85
 0.9
 1.0

julia> itp[0.3]
0.24999999999999997

julia> plot(0:0.01:1.0, [itp[i] for i ∈ 0:0.01:1.0], label = "Interpolation");

julia> scatter!(x, y, label = "Data", legend = :right)

```

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

(I feel a bit bad responding to a visual wizard like you with such a pedestrian plot…)

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 15, 2021, 3:00pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/3 "2021-02-15T15:00:22Z")

</div>

Haha, no, that’s awesome - firmly grounded in reality, not “pedestrian” at all.

Code is great - thanks! You make it look easy! 😂

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [February 15, 2021, 3:16pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/4 "2021-02-15T15:16:41Z")

</div>

Pleasure to be able to help the creator of JuliaMono, which I use heavily wherever I can - in the grand scheme of things that was probably the greater contribution 🙂

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 15, 2021, 4:08pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/5 "2021-02-15T16:08:16Z")

</div>

Thanks!

(There’s a lot of interpolation going on in the font creation application too - the seven weights are interpolated between just a few “masters”. Although the interpolation is carried out automatically, so I never have to think about it.)

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [February 15, 2021, 4:55pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/6 "2021-02-15T16:55:26Z")

</div>

Using the parametric BSplines from the same [Interpolations.jl](https://github.com/JuliaMath/Interpolations.jl) package might be of interest for this problem too:

```julia
using Interpolations, Plots
t = 0:.2:1
x, y = 2sin.(π*t), cos.(π*t)
itp = Interpolations.scale(interpolate([x y], (BSpline(Cubic(Natural(OnGrid()))), NoInterp())), t, 1:2)
tfine = 0:.01:1
xs, ys = [itp(t,1) for t in tfine], [itp(t,2) for t in tfine]
x0, y0 = itp(0.5,1), itp(0.5,2) # interpolate point at t=0.5
plot(xs, ys, aspect_ratio=1, label="BSpline", title="Interpolations.jl parametric BSpline")
scatter!(x, y, label="input points")
scatter!([x0], [y0], ms=5, mc=:red, label="Interpolated") 

```

![Interpolations_parametric_BSpline](https://global.discourse-cdn.com/julialang/original/3X/5/3/53d12f5f6344d6875f1dc9b4e13fb21643416db4.png)

---

<div class="post-metadata">

### Author: ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)
#### Post date: [February 15, 2021, 5:15pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/7 "2021-02-15T17:15:00Z")

</div>

The answers so far pass exactly through all known points, which is not what you originally drew.

There are alternatives using eg least squares fitting instead of interpolation that would give something closer to your original drawing, if that would be of interest.

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 15, 2021, 5:29pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/8 "2021-02-15T17:29:45Z")

</div>

That’s an interesting point! As usual there’s a lot more to it than a non-mathematician would expect… 🙂 )

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 15, 2021, 6:23pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/9 "2021-02-15T18:23:10Z")

</div>

What do these “few equally-spaced values between 0.0 and 1.0” represent?  
(by “equally-spaced”, I assume these are y-values that go with equidistant xs)

---

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [February 15, 2021, 6:24pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/10 "2021-02-15T18:24:18Z")

</div>

There’s an implementation of the [Hobby algorithm](https://link.springer.com/article/10.1007/BF02187690) for TikZ: [http://mirrors.ctan.org/graphics/pgf/contrib/hobby/hobby.pdf](http://mirrors.ctan.org/graphics/pgf/contrib/hobby/hobby.pdf) that I liked a lot when I was trying to define a naturally-looking curve by specifying as few points as possible. It would be great to have something like that for Julia (I don’t think anyone has implemented it yet). But I don’t know how the position on the curve is parameterized, which is essential for your application.

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 15, 2021, 7:08pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/11 "2021-02-15T19:08:49Z")

</div>

These are color channel values, eg red has value 0.85 at 0.5…

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 15, 2021, 7:28pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/12 "2021-02-15T19:28:32Z")

</div>

for animating color change?

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 15, 2021, 7:29pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/13 "2021-02-15T19:29:37Z")

</div>

Yes, smoothly… 🍯

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [February 15, 2021, 7:42pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/14 "2021-02-15T19:42:19Z")

</div>

@dpsanders, in that situation Paul Dierckx is our friend:

```julia
using Dierckx, Plots
t = 0.05:.2:0.95; rt = rand(length(t));
x, y = 2sin.(π*t) .+ 0.3rt, cos.(π*t) .+ 0.2rt
spl = ParametricSpline(t, [x y]', bc="extrapolate", s = 0.1)
tfine = 0:.01:1
xys = evaluate(spl,tfine);
xy0 = evaluate(spl, 0.5) # interpolate point at t=0.5
plot(xys[1,:], xys[2,:], aspect_ratio=1, label="Dierckx.jl parametric spline", title="Dierckx parametric spline")
scatter!(x, y, label="input points", xlimits = (-1.5,2.5))
scatter!([xy0[1]], [xy0[2]], ms=5, mc=:red, label="Interpolated", legend=:bottomleft) 

```

![Dierckx_parametric_spline](https://global.discourse-cdn.com/julialang/original/3X/a/3/a39acbf92d3a50a9701676d67763001ff4c0efe7.png)

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 16, 2021, 9:38am UTC](https://discourse.julialang.org/t/simple-interpolation/55320/15 "2021-02-16T09:38:08Z")

</div>

So far it’s working well:

 ![Screenshot 2021-02-16 at 09.35.24](https://global.discourse-cdn.com/julialang/original/3X/3/4/34edc67286d987648357da5f3070200fd0ce944c.jpeg)

Thanks for the help!

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 16, 2021, 10:46am UTC](https://discourse.julialang.org/t/simple-interpolation/55320/16 "2021-02-16T10:46:56Z")

</div>

Ah! This is so nice. Sorry, couldn’t hold myself and here is colorscheme maker together with palette extraction

```julia
using UrlDownload, ParallelKMeans
using ImageMagick
using ImageCore
using StatsBase

function extract_palette(url, k)
    img = urldownload(url, parser = ImageMagick.load ∘ IOBuffer)
    points = Float64.(channelview(vec(img)))
    res = kmeans(Hamerly(), points, k)
    palette = map(1:k) do i
        RGB(res.centers[:, i]...)
    end
    cnts = sort([x for x in countmap(res.assignments)], by = x -> x[2], rev = true)
    cnts = map(x -> x[1], cnts)
    palette[cnts]
end

```

And this is how it looks together

 ![flameshot-2021-02-16T12-45-11](https://global.discourse-cdn.com/julialang/original/3X/1/f/1fd4f39cc06685719bcd77ba1ed5ce2b452c995b.png)

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [February 16, 2021, 11:18am UTC](https://discourse.julialang.org/t/simple-interpolation/55320/17 "2021-02-16T11:18:00Z")

</div>

Nice work! A few years ago I spent some hours getting something similar to that working:

 ![Screenshot 2021-02-16 at 11.12.40](https://global.discourse-cdn.com/julialang/original/3X/0/f/0f18485bfec31d2761db2bfcd93f374fee53bf8a.jpeg)

… you make it look easy!

I was never convinced that the clustering was doing the right thing - I gather the process is not deterministic, but I sometimes thought there were colors in the result that weren’t in the original… 🙂

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 16, 2021, 3:53pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/18 "2021-02-16T15:53:47Z")

</div>

Never done it myself, but I was told that color clusterization should be done in other colorspaces, not in RGB (maybe it’s already done in ColorSchemeTools). Regarding clusterization, ordering is different, but clustering more or less the same for different runs.

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 16, 2021, 6:36pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/19 "2021-02-16T18:36:03Z")

</div>

L\*a\*b (CIELAB) works well for this.

---

<div class="post-metadata">

### Author: ![Freya\_the\_Goddess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/freya_the_goddess/32/36835_2.png) [@Freya\_the\_Goddess](https://discourse.julialang.org/u/Freya_the_Goddess)
#### Post date: [August 15, 2022, 12:05pm UTC](https://discourse.julialang.org/t/simple-interpolation/55320/20 "2022-08-15T12:05:41Z")

</div>

This is what I need a one to many function graph!
