Skip to content
Advertisement

How to plot spheres in 3d with plotly (or another library)?

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!

enter image description here

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:

Result of the script

If you want smoother spheres, increase the resolution parameter (and check the cstride and rstride parameters to plot_surface).

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement