Unable to plot a sphere surface using Plots package

I am trying to follow a tutorial on youtube for SVD, and the instructor created a sphere using Python. I am trying to translate the code to Julia

n = 100
u = range(-π, π; length = n)
v = range(0, π; length = n)
x = cos.(u) * sin.(v)'
y = sin.(u) * sin.(v)'
z = ones(n) * cos.(v)'

surface(x, y, z)

But i get this error

Failed to show value:
MethodError: Cannot `convert` an object of type Plots.Surface{Matrix{Float64}} to an object of type Vector{Float64}

However when i use plot(x, y, z) it plots a hundred circles
image

The original code is from this video
How can I plot a sphere surface?
Thanks

Using Plots.jl plotly() backend, see this solution.

its not possible with GR backend?

Do not think that gr() handles parametric surfaces in 3D (Makie is best for that).

Thank you. I used plotly() with the same code, but my plot’s ticks are all zeros. Do i have to manually set the ticks? Why it couldn’t be done automatically, or am I missing something?

# using Pkg; Pkg.add("Plotly")
using Plots

n = 100
u = range(-π, π; length = n)
v = range(0, π; length = n)
x = cos.(u) * sin.(v)'
y = sin.(u) * sin.(v)'
z = ones(n) * cos.(v)'

plotly()
surface(x, y, z)

image

This might be widespread issue introduced in Julia 1.6.1 while using older Plots.jl versions.

2 Likes

Thanks a lot!!! Actually you are 100% correct.
It looks like i had installed a pacakge FourierAnalysis which forced my Pkg to install a very old version of Plots, and wouldn’t allow me to upgrade it. I removed the FourierAnalysis package and finally was able to update plots, and the axes are now correct. Thanks!!
I think I understand now why I should activate a new environment in each new project directory!
Thanks

1 Like

Just for the record, a decent sphere can be produced with Plots.jl gr() back-end by splitting it in two (top and bottom surfaces). However, it requires a careful computation of the end points for a nice stitching job and minding the plotting order.

using Plots; gr()

zplus(x,y) = (x^2 + y^2) <= 1 ? sqrt.(abs.(1.0 .- x.^2 .- y.^2)) : NaN
zminus(x,y) = (x^2 + y^2) <= 1 ? -sqrt.(abs.(1.0 .- x.^2 .- y.^2)) : NaN

x = collect(-1:0.01:1);
y = @. (1-x^2)^0.5
y = reshape(permutedims([-y y]),:,1)[:]
x = sort([x; x.+eps()])

surface(x,y,zminus, ratio=:equal,xlims=(-1,1),ylims=(-1,1),zlims=(-1,1))  # isometric
surface!(x,y,zplus, ratio=:equal,xlims=(-1,1),ylims=(-1,1),zlims=(-1,1))  # isometric

Plots_gr_sphere_2_halves

1 Like