# 3D interpolation in Julia

**URL:** https://discourse.julialang.org/t/3d-interpolation-in-julia/117035
**Category:** Numerics
**Tags:** package, interpolations
**Created:** [July 14, 2024, 4:17pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035 "2024-07-14T16:17:47Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [July 14, 2024, 4:17pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/1 "2024-07-14T16:17:47Z")

</div>

I am doing 3D interpolation with the nodes being [x,y,z], where x is a 1\*nx vector, y is 1\*ny,1\*nx, the corresponding values to be interpolated is V which is a nx\*ny\*nz matrix. I use Dierckx for 1d/2d interpolation, but it does not allow for 3d version. My nodes are not uniform. For example, x = [1.2, 1.5, 1.9, 2.9], y = [1.4, 1.6],z = [3.,3.6,4.]. GridInterpolations seem to work, but it cannot evaluate multiple points at the same time after the interpolation step. I prefer to use piecewise cubic spline. I wonder if anyone knows what package suits my need.

---

<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: [July 14, 2024, 4:51pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/2 "2024-07-14T16:51:50Z")

</div>

> [@jgr](#):
>
> GridInterpolations seem to work, but it cannot evaluate multiple points at the same time after the interpolation step

What do you mean by “at the same time”? Can’t you just broadcast the interpolation call or use a comprehension if you want to apply it to a vector of points?

---

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [July 15, 2024, 3:52am UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/3 "2024-07-15T03:52:46Z")

</div>

I meant something like broadcasting. My understanding is that it’s not straightforward to broadcast the interpolation functions in GridInterpolations. I think I’ll write a loop. Thanks!

---

<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: [July 15, 2024, 11:16am UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/4 "2024-07-15T11:16:21Z")

</div>

> [@jgr](#):
>
> My understanding is that it’s not straightforward to broadcast the interpolation functions in GridInterpolations

You could try something like this:

```julia
using GridInterpolations

grid = RectangleGrid(0.:2.0, 0.:2.0, 0.:2.0) # rectangular grid
gridData = rand(3, 3, 3)
x = [0.1 0.2 0.3; 0. 1.5 2.0; 1.3 1.6 0.0; 0.2 0.5 1.0]
interpolate.(Ref(grid), Ref(gridData), eachrow(x))

```

---

<div class="post-metadata">

### Author: ![pitsianis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pitsianis/32/26588_2.png) [@pitsianis](https://discourse.julialang.org/u/pitsianis)
#### Post date: [July 15, 2024, 11:28pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/5 "2024-07-15T23:28:10Z")

</div>

Does this or any other package provide the interpolation for the other direction, that is, given `x` and `fx` and a rectangular `grid`, estimate the values in `griddata`?  
Parallelization wont be as easy because it will require binning the `x` coordinates and then staging the writes into sub grids to avoid conflicting updates on the same `griddata` location.

---

<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: [July 16, 2024, 5:33am UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/6 "2024-07-16T05:33:34Z")

</div>

Packages like GMT.jl or DIVAnd.jl can grid irregular data…

---

<div class="post-metadata">

### Author: ![kylebeggs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kylebeggs/32/43348_2.png) [@kylebeggs](https://discourse.julialang.org/u/kylebeggs)
#### Post date: [July 17, 2024, 2:02pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/7 "2024-07-17T14:02:27Z")

</div>

My package [RadialBasisFunctions.jl](https://github.com/kylebeggs/RadialBasisFunctions.jl) can do this. The function is called `regrid` (see [docs](https://kylebeggs.github.io/RadialBasisFunctions.jl/stable/)). You can map any set of points where you have the function values to any other set of points you wish, for any dimension as well. The input must be a vector of `Tuple` or `SVector` - something you can infer the length of. This is useful if your data is changing and you need to performthe mapping a lot. If you only need it once, it won’t be as fast as other methods, but it might be convenient to use.

```julia
using RadialBasisFunctions
using StaticArrays
using Statistics
using Random

f(x) = 1 + sin(4 * x[1]) + cos(3 * x[1]) + sin(2 * x[2])
N = 1_000
x = map(x -> SVector{2}(rand(MersenneTwister(x), 2)), 1:N)
y = f.(x)

x2 = map(x -> SVector{2}(rand(2)), 1:100)

r = regrid(x, x2)
f_at_x2 = r(y)

```

---

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [July 17, 2024, 3:17pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/8 "2024-07-17T15:17:00Z")

</div>

Thank you.` If you only need it once...`: Do you mean if y is a short vector, then it won’t be as fast?

---

<div class="post-metadata">

### Author: ![kylebeggs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kylebeggs/32/43348_2.png) [@kylebeggs](https://discourse.julialang.org/u/kylebeggs)
#### Post date: [July 17, 2024, 3:29pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/9 "2024-07-17T15:29:35Z")

</div>

Yes, it’s not as fast as other packages if you need to query for different x2 everytime. You can do that, but you have to rebuild everytime. This function is optimal for when you have a known x and x2 and then you just want to get y2 where y is an input. It isn’t clear to me what your exact scenario is. What are your knowns and unknowns/queries?

---

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [July 17, 2024, 9:36pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/10 "2024-07-17T21:36:58Z")

</div>

For my case, my x2 is relatively large: 1042 points. So I think this package may be a good fit. Thanks!

---

<div class="post-metadata">

### Author: ![kylebeggs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kylebeggs/32/43348_2.png) [@kylebeggs](https://discourse.julialang.org/u/kylebeggs)
#### Post date: [July 17, 2024, 10:10pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/11 "2024-07-17T22:10:17Z")

</div>

It’s still a little rough around the edges. It came out of my graduate work. Now that I’ve finished and have more time, I’m going to be dedicating some time to it and tidying it up. Please make issues int he repo for any comments or questions, etc.

---

<div class="post-metadata">

### Author: ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)
#### Post date: [July 18, 2024, 4:29pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/12 "2024-07-18T16:29:56Z")

</div>

There is also [GitHub - eljungsk/ScatteredInterpolation.jl: Interpolation of scattered data](https://github.com/eljungsk/ScatteredInterpolation.jl) which works pretty well !

---

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [July 18, 2024, 6:50pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/13 "2024-07-18T18:50:30Z")

</div>

Thanks. I wonder which method you use in your package. Is it possible to incorporate cubic spline? I’m writing a code doing this on my own. But I’m not an expert in Julia and coding, so if someone could provide a high performance package with high speed that would be great! If cubic spline is not the method you want to incorporate, that is totally fine!

---

<div class="post-metadata">

### Author: ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)
#### Post date: [July 18, 2024, 8:32pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/14 "2024-07-18T20:32:22Z")

</div>

Given how things are implemented in ScatteredInterpolation, it should be fairly easy to add your own RBF kernel if not already available.

---

<div class="post-metadata">

### Author: ![kylebeggs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kylebeggs/32/43348_2.png) [@kylebeggs](https://discourse.julialang.org/u/kylebeggs)
#### Post date: [July 18, 2024, 9:07pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/15 "2024-07-18T21:07:01Z")

</div>

As for ScatteredInterpolation.jl, you can add your own kernels as well. You just need to make a new type which is subtype of `AbstractRadialBasis`. Is there a reason you need to do cubic splines specifically? ScatteredInterpolations.jl is a good choice.

---

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [July 19, 2024, 5:07am UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/16 "2024-07-19T05:07:36Z")

</div>

Okay, I’ll take a look at it. Thank you. I want to use cubic spline because for the specific problems I’m solving, most previously related research uses cubic spline which proves to have a better performance.

---

<div class="post-metadata">

### Author: ![kylebeggs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kylebeggs/32/43348_2.png) [@kylebeggs](https://discourse.julialang.org/u/kylebeggs)
#### Post date: [July 19, 2024, 1:26pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/17 "2024-07-19T13:26:32Z")

</div>

Over RBFs with polynomials? In terms of accuracy, these packages perform better in general than vanilla cubic splines

---

<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: [July 19, 2024, 4:07pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/18 "2024-07-19T16:07:32Z")

</div>

> [@jgr](#):
>
> for the specific problems I’m solving, most previously related research uses cubic spline which proves to have a better performance.

I would get something working first, and only worry about finding better algorithms when you see where the problems and performance bottlenecks are.

(Also, the relative performance of different algorithms can be very implementation-dependent, so I wouldn’t assume that someone else’s experience with another language and another library will be identical to yours.)

---

<div class="post-metadata">

### Author: ![JoshuaLampert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshualampert/32/205964_2.png) [@JoshuaLampert](https://discourse.julialang.org/u/JoshuaLampert)
#### Post date: [July 19, 2024, 6:51pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/19 "2024-07-19T18:51:09Z")

</div>

I also have [KernelInterpolation.jl](https://github.com/JoshuaLampert/KernelInterpolation.jl), which is similar to ScatteredInterpolations.jl and RadialBasisFunctions.jl.

---

<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: [July 19, 2024, 11:06pm UTC](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035/20 "2024-07-19T23:06:25Z")

</div>

@JoshuaLampert, FYI, I tried your excellent package for interpolating the scattered points of the sin(x\*y) function as in the example [in this post](https://discourse.julialang.org/t/plot-3d-data-in-a-2d-contour-plot/71251/2), and got what appears to be excellent results for that type of input data:

 ![KernelInterpolation_of_sin_of_xy](https://global.discourse-cdn.com/julialang/original/3X/d/f/dfbcb168dbe77d50c66ceda6fc38f12d8709b10d.png)

> **KernelInterpolation code**
>
> ```julia
> using KernelInterpolation, Plots
> 
> # 1 - INPUT DATA:
> n = 200
> xs, ys = 2π*(rand(n) .- 0.5), 2π*(rand(n) .- 0.5)
> zs = 100*sin.(xs .* ys)
> 
> # 2 - KERNEL INTERPOLATION:
> nodes = NodeSet([xs ys])
> values = zs
> kernel = GaussKernel{dim(nodes)}(shape_parameter = 1.0)
> itp = KernelInterpolation.interpolate(nodes, values, kernel)
> N = 100
> nodeset = homogeneous_hypercube(N, (-π, -π), (π, π))
> itp_values = itp.(nodeset)
> 
> # 3 - PLOT RESULTS:
> x = unique(values_along_dim(nodeset, 1))
> y = unique(values_along_dim(nodeset, 2))
> heatmap(x, y, reshape(itp_values, (N,N))', ratio=1, lims=(-π,π))
> scatter!(xs, ys, marker_z = zs, ms=3, msw=0.5)
> 
> ```

[Next page](https://discourse.julialang.org/t/3d-interpolation-in-julia/117035.md?page=2)
