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!
Advertisement
Answer
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
).