Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 243
NeStack Avatar asked Dec 30 '25 13:12

NeStack


1 Answers

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).

like image 62
azelcer Avatar answered Jan 01 '26 02:01

azelcer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!