Issue
I am struggling with plotting something, that I thought should be really simple. I have a dataframe/table df
that contains the coordinates x,y,z of spheres. Additionally, in a separate column, it contains the radius of these spheres. How can I make with plotly a 3d plot of the spheres in space with their correct radius being used?
The closest I have come to making this plot reality is this code:
import plotly.express as px
import plotly.graph_objects as go
x =y=z = np.arange(1,4)
fig = go.Figure()
fig.add_trace(go.Scatter3d(
mode='markers',
x=x,
y=y,
z=z,
marker=dict(color=px.colors.qualitative.D3,size=[50, 5, 25],sizemode='diameter'
)
)
)
This produces almost what I want (see below), but notice that the sizes of the spheres are not correct - the ratios between the sphere sizes are correct, but I want size
to provide the absolute size of the spheres in the plot. How can I make this plot work with plotly (or worst case with another library)? Tnx!
Solution
When you use markers, the size is usually specified in pixels (either area or diameter). The docs state precisely that.
I have never used plotly
, but I am pretty sure it will be easy to convert this script using matplotlib
to use plotly
(see here.)
import numpy as np
import matplotlib.pyplot as plt
from itertools import repeat # just for the example
def makesphere(x, y, z, radius, resolution=10):
"""Return the coordinates for plotting a sphere centered at (x,y,z)"""
u, v = np.mgrid[0:2*np.pi:resolution*2j, 0:np.pi:resolution*1j]
X = radius * np.cos(u)*np.sin(v) + x
Y = radius * np.sin(u)*np.sin(v) + y
Z = radius * np.cos(v) + z
return (X, Y, Z)
fig = plt.figure("Spheres")
ax = fig.add_subplot(projection='3d')
for x, y, z, radius, in zip(*repeat(np.arange(1,4),3), [.1, .5, .75]):
X, Y, Z = makesphere(x, y, z, radius)
ax.plot_surface(X, Y, Z, color="r")
Result:
If you want smoother spheres, increase the resolution
parameter (and check the cstride
and rstride
parameters to plot_surface
).
Answered By - azelcer
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.