# How to plot a 3D contour surface with Makie

**URL:** https://discourse.julialang.org/t/how-to-plot-a-3d-contour-surface-with-makie/103822
**Category:** Visualization
**Tags:** plotting, makie
**Created:** [September 13, 2023, 5:03pm UTC](https://discourse.julialang.org/t/how-to-plot-a-3d-contour-surface-with-makie/103822 "2023-09-13T17:03:24Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![yhchang96](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yhchang96/32/36499_2.png) [@yhchang96](https://discourse.julialang.org/u/yhchang96)
#### Post date: [September 13, 2023, 5:03pm UTC](https://discourse.julialang.org/t/how-to-plot-a-3d-contour-surface-with-makie/103822/1 "2023-09-13T17:03:24Z")

</div>

Suppose I want to plot the solution to the equation `-x^3+r*x+h=0` in 3D, with `r` and `h` on the X-Y plane, and `x` as the z-axis to demonstrate the cusp catastrophe in bifurcation. In Mathematica, I have something like this:

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

What would be the best way to make this 3D plot in Makie? It looks like `surface` requires `x` as a function of `r` and `h`, but the surface plot has regions with multiple ‘layers’, whereas `contour3d` plots lines if I’m not mistaken.

---

<div class="post-metadata">

### Author: ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)
#### Post date: [September 13, 2023, 5:45pm UTC](https://discourse.julialang.org/t/how-to-plot-a-3d-contour-surface-with-makie/103822/2 "2023-09-13T17:45:56Z")

</div>

I don’t think this is entirely possible with Makie currently, but there is similar functionality for plotting isoregions that are close to what you want, see the documentation here: [volume · Makie](https://docs.makie.org/stable/reference/plots/volume/index.html).

For your example, it would be something like

```julia
using GLMakie
f(r,h,x) = -x^3+r*x+h
var_range = range( -3 , 3 ; length = 100 )
F = [f(r,h,x) for r in var_range, h in var_range, x in var_range]

fig = Figure()
ax = Axis3( fig[1,1] , xlabel = "r" , ylabel = "h" , zlabel = "x" )
volume!( ax , var_range , var_range , var_range , F ; algorithm = :iso, isorange = 0.05, isovalue = 0.0 )
fig

```

The `isovalue`is the RHS of your equation (here, 0), and the isorange is a range of values close to the isovalue that will be included in the volume plot.

Edit: Using some other packages, there are ways of doing this:

```julia
using GeometryBasics
using MarchingCubes
using GLMakie

f(r,h,x) = -x^3+r*x+h
var_range = range( -3 , 3 ; length = 100 )
s = collect( var_range )

mcd = MC( F ; x = s , y = s , z = s )
march(mcd)
msh = MarchingCubes.makemesh(GeometryBasics, mcd)

fig = Figure()
ax = Axis3( fig[1,1] , xlabel = "r" , ylabel = "h" , zlabel = "x" )
mesh!( ax , msh ; color = :orange )
fig 

```

---

<div class="post-metadata">

### Author: ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)
#### Post date: [September 13, 2023, 8:31pm UTC](https://discourse.julialang.org/t/how-to-plot-a-3d-contour-surface-with-makie/103822/3 "2023-09-13T20:31:58Z")

</div>

You might need to work on the shading, but something like this gets you the basic shape:

```julia
using GLMakie
F(h,r,x) = h + r*x - x^3
xs = ys = zs = range(-3, 3, length=100)
contour(xs, ys, zs, F, levels=[0])

```
