# Parametric surface plot of custom indexed array

**URL:** <https://discourse.julialang.org/t/parametric-surface-plot-of-custom-indexed-array/71359>\
**Category:** General Usage\
**Tags:** plotting\
**Created:** [November 12, 2021, 1:41am UTC](https://discourse.julialang.org/t/parametric-surface-plot-of-custom-indexed-array/71359 "2021-11-12T01:41:43Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Oko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oko/32/22734_2.png) [@Oko](https://discourse.julialang.org/u/Oko)\
**Post date:** [November 12, 2021, 1:41am UTC](https://discourse.julialang.org/t/parametric-surface-plot-of-custom-indexed-array/71359/1 "2021-11-12T01:41:43Z")

</div>

I am struggling with something which seems pretty trivial problem. Namely, I have a stochastic process on a random graph depending on the two parameters. The first parameter is the probability of an edge between two nodes of a random graph. The second parameter is the number of nodes in a certain state at the beginning of the process. The output is an integer function depending on those two parameters. I would like to get a surface plot

> surface(p\_edge, num\_ian, my\_function(p\_edge, num\_ian))

The following is really naive code which avoids custom indices but I am not 100 sure that p\_edge and num\_ian are mapped with the correct valued of the function. Ideally, I would like to iterate a 2D array over two directed linearly ordered sets instead of essentially introducing auxiliary variables to avoid custom index sets.

```julia
#!/usr/bin/julia
using Debugger
using Graphs
using SparseArrays
using StatsBase
using Statistics
using Plots;plotlyjs()

include("my_function.jl")

n = 200
p_edge = 0.01:0.01:0.5
num_ian = 10:1:100

target_surf = Matrix{Int64}(undef, size(p_edge,1), size(num_ian,1)) 

for i = 1:size(p_edge,1)
        g = erdos_renyi(n, p_edge[i]; is_directed=true, seed=-1)
        for j = 1:size(num_ian,1)
                ia = sample(1:n,num_ian[j]; replace=false, ordered=true)
                target_surf[i,j] = my_function(g,ia)
        end
end
display(target_surf)
plot(p_edge, num_ian, target_surf, st = :surface, xlabel = "p_edge", ylabel = "num_ian", zlabel = "mine > 1")

```

---

<div class="post-metadata">

**Author:** ![Oko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oko/32/22734_2.png) [@Oko](https://discourse.julialang.org/u/Oko)\
**Post date:** [November 16, 2021, 9:37pm UTC](https://discourse.julialang.org/t/parametric-surface-plot-of-custom-indexed-array/71359/2 "2021-11-16T21:37:59Z")

</div>

Due to my low trust level I can’t edit the post so I am replying to my own question. The above problem can be trivially seen as a parametric surface plot. What I was looking for is the equivalent of Mathematica’s [ParametricPlot3D](https://reference.wolfram.com/language/ref/ParametricPlot3D.html) function.

It is definitely doable using vanilla Plots package but the documentation is a bit lacking and it is definitely  
[not a one-liner](https://discourse.julialang.org/t/drawing-parametric-surfaces-in-plots-jl/36560/9). I stumbled onto the package  
[Axl](http://axl.inria.fr/doc/Axl.jl/fcts/parametric/) that is supposedly doing what I want but I don’t want to turn my Julia installation into a package kitchen-sink.

This is a minimal working example of the helicoid plot

```julia
#!/usr/bin/julia
using Debugger
using Plots;plotlyjs()

X(r,t) = r*cos(t)
Y(r,t) = r*sin(t)
Z(r,t) = 3*t
 
r_range = LinRange(0, 1, 200) 
t_range = LinRange(0, 4*pi, 400)

x_grid = [X(r,t) for r in r_range, t in t_range]
y_grid = [Y(r,t) for r in r_range, t in t_range]
z_grid = [Z(r,t) for r in r_range, t in t_range]

plot(x_grid, y_grid, z_grid, st = :surface, xlabel = "x", ylabel = "y", zlabel = "z")

```

And the output

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