# Surface plot using plots.jl

**URL:** https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956
**Category:** General Usage
**Tags:** plots
**Created:** [September 17, 2023, 7:14pm UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956 "2023-09-17T19:14:10Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![yosuga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yosuga/32/52638_2.png) [@yosuga](https://discourse.julialang.org/u/yosuga)
#### Post date: [September 17, 2023, 7:14pm UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/1 "2023-09-17T19:14:10Z")

</div>

I have two very basic questions about surface plots.

One is that when I have a dataset `S = [(x1, y1, z1), (x2, y2, z2), ..., (xn, yn, zn)]`, how can I create a surface plot for `z`? Here, `(xi, yi)≠(xj, yj)` for `i≠j` are guaranteed. For example, `plot(X, Y, Z, st=:surface)` doesn’t work for `X = [x1, x2, ..., xn]`, `Y = [y1, y2, ..., yn]`, and `Z = [z1, z2, ..., zn]`.

The other question is, can I obtain interpolated data points, meaning data points that are not present in the original dataset, from the surface plot function?

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [September 18, 2023, 3:41am UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/2 "2023-09-18T03:41:11Z")

</div>

> [@yosuga](#):
>
> One is that when I have a dataset `S = [(x1, y1, z1), (x2, y2, z2), ..., (xn, yn, zn)]`, how can I create a surface plot for `z`? Here, `(xi, yi)≠(xj, yj)` for `i≠j` are guaranteed. For example, `plot(X, Y, Z, st=:surface)` doesn’t work for `X = [x1, x2, ..., xn]`, `Y = [y1, y2, ..., yn]`, and `Z = [z1, z2, ..., zn]`.

For a surface, one would typically have a grid of domain points and a `z` value defined for each.  
See for example: [3D surface with axis guides · Plots](https://docs.juliaplots.org/dev/gallery/gr/generated/gr-ref050/#gr_ref050)

> [@yosuga](#):
>
> The other question is, can I obtain interpolated data points, meaning data points that are not present in the original dataset, from the surface plot function?

The Interpolations.jl package may be useful: [General usage · Interpolations.jl](https://juliamath.github.io/Interpolations.jl/latest/interpolations/) , possibly using “gridded interpolation”([Interpolation algorithms · Interpolations.jl](https://juliamath.github.io/Interpolations.jl/latest/control/#Gridded-interpolation))

---

<div class="post-metadata">

### Author: ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)
#### Post date: [September 18, 2023, 6:32am UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/3 "2023-09-18T06:32:13Z")

</div>

You also might be interested in [GitHub - mdmaas/PColorPlot.jl: Adding interpolated heatmaps to Plots.jl via a pcolor recipe](https://github.com/mdmaas/PColorPlot.jl). That should be straightforward to apply to surfaces also.

---

<div class="post-metadata">

### Author: ![yosuga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yosuga/32/52638_2.png) [@yosuga](https://discourse.julialang.org/u/yosuga)
#### Post date: [September 20, 2023, 3:46am UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/4 "2023-09-20T03:46:15Z")

</div>

> [@jd-foster](#):
>
> For a surface, one would typically have a grid of domain points and a `z` value defined for each.  
> See for example: [3D surface with axis guides · Plots](https://docs.juliaplots.org/dev/gallery/gr/generated/gr-ref050/#gr_ref050)

So, do we always need a grid? I mean, for a region that cannot be represented by a tensor product (or direct product) of `X` and `Y`, is it not possible to create a surface plot?

> [@jd-foster](#):
>
> The Interpolations.jl package may be useful: [General usage · Interpolations.jl](https://juliamath.github.io/Interpolations.jl/latest/interpolations/) , possibly using “gridded interpolation”([Interpolation algorithms · Interpolations.jl](https://juliamath.github.io/Interpolations.jl/latest/control/#Gridded-interpolation))

This looks good. Thank you!

```julia
using Plots
using Interpolations

#original data
xs = 0.1:0.05:2.0
ys = 0.2:0.1:2.0
X = [x for x = xs for _ = ys]
Y = [y for _ = xs for y = ys]
Z = [1/x + y*x^2 for x in xs for y in ys]

#interpolations
ZIp = [1/x + y*x^2 for x in xs, y in ys] #make a length(xs)×length(ys) matrix
interp_linear = linear_interpolation((xs, ys), ZIp) # linear interpolation
interp_cubic = cubic_spline_interpolation((xs, ys), ZIp) # cubic spline interpolation
#define a interpolation function
ZIp1(x,y) = interp_linear(x,y)
ZIp2(x,y) = interp_cubic(x,y)

#interpolated region
xsIp = 0.1:0.01:2.0
ysIp = 0.2:0.05:2.0
XIp = [x for x = xsIp for _ = ysIp]
YIp = [y for _ = xsIp for y = ysIp]

plot(XIp,YIp,ZIp1.(XIp,YIp),st=:scatter,markercolor=:blue,markerstrokecolor=:blue,markerstrokewidth=0,markersize=3,label="linear interpolation")
plot!(X,Y,Z,st=:scatter,markercolor=:pink,markerstrokecolor=:pink,markerstrokewidth=0,markersize=2,label="original data")
fig1 = plot!(xlabel="x",ylabel="y",zlabel="z",foreground_color_legend=nothing)
plot(XIp,YIp,ZIp2.(XIp,YIp),st=:scatter,markercolor=:blue,markerstrokecolor=:blue,markerstrokewidth=0,markersize=3,label="cubic spline interpolation")
plot!(X,Y,Z,st=:scatter,markercolor=:pink,markerstrokecolor=:pink,markerstrokewidth=0,markersize=2,label="original data")
fig2 = plot!(xlabel="x",ylabel="y",zlabel="z",foreground_color_legend=nothing)
plot(fig1,fig2,layout=(1,2))

```

 ![interpolations](https://global.discourse-cdn.com/julialang/original/3X/6/5/655aff4befd6950c9891d793cca4963f93e24614.png)

---

<div class="post-metadata">

### Author: ![yosuga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yosuga/32/52638_2.png) [@yosuga](https://discourse.julialang.org/u/yosuga)
#### Post date: [September 20, 2023, 3:52am UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/5 "2023-09-20T03:52:01Z")

</div>

Thanks! This also looks promising, but how can I create a function (or array) like `ZIp1(x, y)` as I mentioned in the reply to @jd-foster? I need the underlying numerical data itself, not an image.

---

<div class="post-metadata">

### Author: ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)
#### Post date: [September 20, 2023, 11:02am UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/6 "2023-09-20T11:02:12Z")

</div>

This uses [GitHub - kbarbary/Dierckx.jl: Julia package for 1-d and 2-d splines](https://github.com/kbarbary/Dierckx.jl) for the interpolation

---

<div class="post-metadata">

### Author: ![yosuga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yosuga/32/52638_2.png) [@yosuga](https://discourse.julialang.org/u/yosuga)
#### Post date: [September 21, 2023, 6:49am UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/7 "2023-09-21T06:49:03Z")

</div>

It went well. Thank you!

```julia
using Plots
using Dierckx

#original data
xs = 0.1:0.05:2.0
ys = 0.2:0.1:2.0
X = [x for x = xs for _ = ys]
Y = [y for _ = xs for y = ys]
Z = [1/x + y*x^2 for x in xs for y in ys]

#interpolations
ZIp = [1/x + y*x^2 for x in xs, y in ys] #make a length(xs)×length(ys) matrix
interp = Spline2D(xs, ys, ZIp) # interpolation
#define a interpolation function
ZIp1(x,y) = evaluate(interp,x,y)

#interpolated region
xsIp = 0.1:0.01:2.0
ysIp = 0.2:0.05:2.0
XIp = [x for x = xsIp for _ = ysIp]
YIp = [y for _ = xsIp for y = ysIp]

plot(XIp,YIp,ZIp1.(XIp,YIp),st=:scatter,markercolor=:blue,markerstrokecolor=:blue,markerstrokewidth=0,markersize=3,label="linear interpolation")
plot!(X,Y,Z,st=:scatter,markercolor=:pink,markerstrokecolor=:pink,markerstrokewidth=0,markersize=2,label="original data")
plot!(xlabel="x",ylabel="y",zlabel="z",foreground_color_legend=nothing)

```

 ![Dierckx](https://global.discourse-cdn.com/julialang/original/3X/b/c/bc991728a3dfef75e57c6d60ce2af6a20d6cf4e0.png)

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [September 24, 2023, 2:22pm UTC](https://discourse.julialang.org/t/surface-plot-using-plots-jl/103956/8 "2023-09-24T14:22:00Z")

</div>

You might find ApproxFun interesting too: [Home · ApproxFun.jl](https://juliaapproximation.github.io/ApproxFun.jl/latest/)

See also the FAQ.
