Single-color 3D surface plot

I’m trying to plot a 3D surface as a single, semi-transparent color. Here’s what I’ve tried:

using PlotlyJS

f(x, y) = 10 .* sin.(x./5) .+ 8 .* cos.(y./7) .+ y./30;
xs = ys = 0:1:100; 
zs = f.(xs', ys);

plot(surface(x=xs, y=ys, z=zs, color=:black, opacity=0.5))

Above, you see I’ve tried to set color=:black, and I’ve also tried surfacecolor=:black, but these requests seem to be ignored in favor of color-scaling based on z value.

How do I make a plain black surface?

Would the Greys colorscale please:

plot(surface(x=xs, y=ys, z=zs, colorscale="Greys", opacity=0.5))

Thanks @rafael.guerra, but not quite. The goal is just to make the surface a single color.

Close to this?

using GMT

C = makecpt(range=(-15,0), cmap=200);
imshow("ackley", view=(159,30), cmap=C, shade=true, transparency=50, figname=:xx)

Fwiw, this does pick a single color from the Greys palette:

plot(surface(x=xs, y=ys, z=zs, surfacecolor=0*zs, colorscale="Greys", opacity=0.5))

With GR(at least, maybe with other too), you can use cgrad() with identical initial and end colors, to achieve that:

julia> using Plots

julia> xs = ys = 0:1:100;

julia> zs = f.(xs', ys);

julia> surface(xs, ys, zs, xlabel = "longer xlabel", ylabel = "longer ylabel", zlabel = "longer zlabel", c=cgrad([:green,:green]))

image

To get a single-color surface you should define a constant colorscale=[[0, "black"], [1, "black"]]
or
colorscale=[[0, "#000000"], [1, "#000000"]]

plot(surface(x=xs, y=ys, z=zs, 
             colorscale=[[0, "black"], [1, "black"]], 
             showscale=false,
             opacity=0.5,
             lighting=attr(ambient=0.5, 
                           diffuse=0.4,
                           fresnel=0.4,        
                           specular=0.5,
                           roughness=0.5),
             lightposition=attr(x=100,
                                y=100,
                                z=1000)
        ),
    Layout(width=600, height=400, font_size=10))
2 Likes

In case you’re wondering what @empet 's plot looks like:

1 Like

Makie’s solution looks like this:

using GLMakie
f(x, y) = 10 .* sin.(x./5) .+ 8 .* cos.(y./7) .+ y./30;
xs = ys = 0:1:100; 
zs = f.(xs', ys)
surface(xs, ys, zs; colormap=[(:black,0.5)], transparency=true)

Yes, this is exactly what I was looking for, and I appreciate the fancy lighting options. Thank you!

Question: Is there any hit to performance when the surface is colorscaled? I only ask because MATLAB has an easier time rendering a solid blue surface than a color-scaled blue surface. In our current solution, we’ve scaled from one color to the same color, so I’m wondering if that impacts the rendering speed.

There is no other mean to define a surface in PlotlyJS beside giving a colorscale. That’s why I don’t think that colorscale could affect the performance.

1 Like