# Fill a curve in 3D

**URL:** <https://discourse.julialang.org/t/fill-a-curve-in-3d/37890>\
**Category:** Visualization\
**Tags:** plots\
**Created:** [April 20, 2020, 11:25am UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890 "2020-04-20T11:25:12Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [April 20, 2020, 11:25am UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/1 "2020-04-20T11:25:12Z")

</div>

I want to plot a complex impedance value as a function of frequency.

This results in a line in 3D(real, imaginary, frequency).  
How do I fill the area between the line and the z=0 coordinate in 3D.  
I tried fillrange and ribbon, but I could not get it to work in Plots.jl

Something like this can be found on page 295:

> **[187ImpSpectroscopy.pdf](https://jrossmacdonald.com/jrm/wp-content/uploads/187ImpSpectroscopy.pdf)**
>
> 991.76 KB

---

<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:** [April 20, 2020, 12:03pm UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/2 "2020-04-20T12:03:02Z")

</div>

In PGFPlotsX, I would suggest this example as a starting point:

[https://kristofferc.github.io/PGFPlotsX.jl/dev/examples/gallery.html#D-Waterfall-1](https://kristofferc.github.io/PGFPlotsX.jl/dev/examples/gallery.html#D-Waterfall-1)

I am not aware of something similar for Plots.jl, but see the original topic:

> [@How can I make this plot?](https://discourse.julialang.org/t/how-can-i-make-this-plot/31278/):
>
> I came across [this article on Freakonometrics](https://freakonometrics.hypotheses.org/9593) and it has the following really nice plot in it (generated with R, I believe): [image] Has anyone seen anything similar plotted in Julia or does anyone know if this is at least possible with Julia?

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [April 20, 2020, 12:55pm UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/3 "2020-04-20T12:55:18Z")

</div>

Don’t know if it applies, but in [Gnuplot.jl](https://github.com/gcalderone/Gnuplot.jl) is quite easy:

```julia
x = 0.:0.05:3;
y = 0.:0.05:3;
z = @. sin(x) * exp(-(x+y))

using Gnuplot
@gsp xlab="X" ylab="Y" linetypes(:Set1_5, lw=3) :-
@gsp :- "set style fill transparent solid 0.3" :-
@gsp :- "set xyplane at 0" "set grid" :-
@gsp :- x y z z.*0 z "w zerror t 'Data'" :-
@gsp :- x.*0 y z "w l notit" :- # projection on x=0
@gsp :- x y.*0 z "w l notit" # projection on y=0
save(term="pngcairo", output="output.png")

```

![output](https://global.discourse-cdn.com/julialang/original/3X/b/8/b8b49ab607a76a390ec3027834999ef83dd94fbe.png)

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [July 1, 2020, 11:28am UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/4 "2020-07-01T11:28:00Z")

</div>

Nice, what about increase transparency in the shaded area (area\_gradient)? As in here: [Area Chart with Gradient | Vega-Lite](https://vega.github.io/vega-lite/examples/area_gradient.html)

---

<div class="post-metadata">

**Author:** ![Allan\_Baker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/allan_baker/32/42645_2.png) [@Allan\_Baker](https://discourse.julialang.org/u/Allan_Baker)\
**Post date:** [July 1, 2020, 4:01pm UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/5 "2020-07-01T16:01:26Z")

</div>

Is this possible with a plots backend? I want to draw in 3D space a 2D polygon so that the disk or ellipse can be rotated. All I am able to get is an unfilled line. Same commands create a filled shape if 2D points are used. Where do I need to look?

---

<div class="post-metadata">

**Author:** ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)\
**Post date:** [April 7, 2021, 8:44pm UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/6 "2021-04-07T20:44:31Z")

</div>

Right, how to do this with Plots.jl? This can be don in 2D [using `plot(x, y, fillrange=0)`](https://stackoverflow.com/questions/48334036/how-to-fill-area-between-curves-with-plots-jl), but this doesn’t work in 3D.

---

<div class="post-metadata">

**Author:** ![cadaverous](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cadaverous/32/47289_2.png) [@cadaverous](https://discourse.julialang.org/u/cadaverous)\
**Post date:** [March 1, 2024, 7:19am UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/7 "2024-03-01T07:19:21Z")

</div>

I know this is kind of old, but I implemented this functionality using mesh3d:

```julia
function fill_between3d(x1, y1, z1, x2, y2, z2)
    n = length(x1)
    x = [x1; x2]
    y = [y1; y2]
    z = [z1; z2]
    bottom_edge = 0:n-2
    top_edge = 1:n-1
    connect1 = [[i for i ∈ bottom_edge]; [2n-i for i ∈ top_edge]]
    connect2 = [[i+1 for i ∈ bottom_edge]; [2n-i-1 for i ∈ top_edge]]
    connect3 = [[n+i+1 for i ∈ bottom_edge]; [n-i-1 for i ∈ top_edge]]
    connect = (connect1, connect2, connect3)
    return (x, y, z, connect)
end

```

Then with GR backend:

```julia
x = 0.:0.05:3;
y = 0.:0.05:3;
z = @. sin(x) * exp(-(x+y))

gr()
plot3d(zero(x), y, z; linecolor=:blue, linewidth=2, label=nothing)
plot3d!(x, y, z; linecolor=:red, linewidth=2, label="data")
meshx, meshy, meshz, connections = fill_between3d(x, y, z, x, y, zero(z))
# linewidth=0. is only necessary for gr() backend it seems...
mesh3d!(meshx, meshy, meshz, connections=connections, color=:red, alpha=0.4, linewidth=0., label=nothing)
# for pgfplotsx():
# mesh3d!(meshx, meshy, meshz, connections=connections, color=:red, fill_opacity=0.4, draw_opacity=0., label=nothing)
plot3d!(x, zero(y), z; linecolor=:green, linewidth=2, label=nothing)

```

 ![fill_between3d_example_gr](https://global.discourse-cdn.com/julialang/original/3X/4/c/4c720a45f88be1abbcef7fd944cf54179d80b38a.png)

and with some other backends:

`plotlyjs()`:

 ![fill_between3d_example_plotlyjs](https://global.discourse-cdn.com/julialang/original/3X/2/2/2277f5f5623724b062914650d11ea45d5dd9b82b.png)

`pythonplot()`:

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

`pgfplotsx()`:  
This required a couple extra parameters in the call to `mesh3d` to enable the transparency and hide the mesh grid-lines

```julia
mesh3d!(meshx, meshy, meshz, connections=connections, fill_opacity=0.4, draw_opacity=0., color=:red)

```

 ![fill_between3d_example_pgfplotsx](https://global.discourse-cdn.com/julialang/original/3X/2/1/215da48150c0e5d0aaaeb727a6340cf3e8bf9e7e.png)

---

<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:** [March 1, 2024, 8:02am UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/8 "2024-03-01T08:02:46Z")

</div>

Here’s a solution using Makie:

```julia
using GLMakie

x = 0:0.05:3;
y = 0:0.05:3;
z = @. sin(x) * exp(-(x+y))

fig = Figure(size=(400, 300))
ax = Axis3(fig[1,1], limits=((0,3), (0,3), (0,0.2)),
           azimuth=0.3, elevation=0.4)
lines!(Point3f.(x, 0, z))
lines!(Point3f.(0, y, z))
band!(Point3f.(x, y, 0), Point3f.(x, y, z), color=(:red, 0.5))
fig

```

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

I used GLMakie because CairoMakie handles the transparency poorly for some reason:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/8/783149f5d27c59d516c5edde21ad1eadeff8c8eb.png)

---

<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:** [August 17, 2024, 2:41pm UTC](https://discourse.julialang.org/t/fill-a-curve-in-3d/37890/9 "2024-08-17T14:41:57Z")

</div>

This is a great thread, and I’m happy to add a different approach using Plots.jl and parametric surfaces, which has the potential to be extended:

![Plots_plotlyjs_fill_3D_curve](https://global.discourse-cdn.com/julialang/original/3X/3/3/33c9766dfc3813e38396009048da25a06c0a810b.png)

> **Plots' plotlyjs() code**
>
> ```julia
> using Plots; plotlyjs()
> 
> f(x, y) = sin(x) * exp(-(x+y))
> 
> x = y = range(0, 3, 500)
> z = @. f(x, y)
> 
> θ = atand(y[end], x[end])
> u, v = hypot.(x, y), range(0, maximum(z), 200)
> X = [u * cosd(θ) for u in u, _ in v]
> Y = [u * sind(θ) for u in u, _ in v]
> Z = [0 ≤ v ≤ f(u*cosd(θ), u*sind(θ)) ? v : NaN for u in u, v in v]
> 
> Plots.surface(X, Y, Z, c=:reds, fillalpha=0.7, colorbar=false)
> Plots.plot!(x, y, z, c=:red, lw=3)
> Plots.plot!(x, 0*y, z, c=:green, lw=2)
> Plots.plot!(0*x, y, z, c=:blue, lw=2)
> 
> ```
