如何使用 plotly(或其他库)绘制 3d 球体?
How to plot spheres in 3d with plotly (or another library)?
我正在努力策划一些我认为应该非常简单的事情。我有一个 dataframe/table df
,其中包含球体的坐标 x、y、z。此外,在一个单独的列中,它包含这些球体的半径。如何使用正确的半径绘制 space 中球体的 3d 图?
我最接近实现这个情节的是这段代码:
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'
)
)
)
这几乎可以生成我想要的结果(见下文),但请注意球体的大小不正确 - 球体大小之间的比率是正确的,但我希望 size
提供绝对大小图中的球体。我怎样才能让这个情节与 plotly 一起工作(或者最坏的情况与另一个图书馆一起工作)?谢谢!
当您使用标记时,通常以像素(面积或直径)为单位指定大小。文档状态 precisely that.
我从未使用过 plotly
,但我很确定将使用 matplotlib
的脚本转换为使用 plotly
会很容易(请参阅 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")
结果:
如果您想要更平滑的球体,请增加 resolution
参数(并将 cstride
和 rstride
参数检查为 plot_surface
)。
根据 azelcer 的回答,我设法生成了以下代码,用 plotly
绘制球体:
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
def ms(x, y, z, radius, resolution=20):
"""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)
df = pd.read_csv('xyzr_sphere_coordinates.txt')
data = []
for index, row in df.iterrows():
(x_pns_surface, y_pns_surface, z_pns_suraface) = ms(row.x, row.y, row.z, row.r)
data.append(go.Surface(x=x_pns_surface, y=y_pns_surface, z=z_pns_suraface, opacity=0.5))
fig = go.Figure(data=data)
fig.show()
它导致这个 3d 互动人物:
我正在努力策划一些我认为应该非常简单的事情。我有一个 dataframe/table df
,其中包含球体的坐标 x、y、z。此外,在一个单独的列中,它包含这些球体的半径。如何使用正确的半径绘制 space 中球体的 3d 图?
我最接近实现这个情节的是这段代码:
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'
)
)
)
这几乎可以生成我想要的结果(见下文),但请注意球体的大小不正确 - 球体大小之间的比率是正确的,但我希望 size
提供绝对大小图中的球体。我怎样才能让这个情节与 plotly 一起工作(或者最坏的情况与另一个图书馆一起工作)?谢谢!
当您使用标记时,通常以像素(面积或直径)为单位指定大小。文档状态 precisely that.
我从未使用过 plotly
,但我很确定将使用 matplotlib
的脚本转换为使用 plotly
会很容易(请参阅 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")
结果:
如果您想要更平滑的球体,请增加 resolution
参数(并将 cstride
和 rstride
参数检查为 plot_surface
)。
根据 azelcer 的回答,我设法生成了以下代码,用 plotly
绘制球体:
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
def ms(x, y, z, radius, resolution=20):
"""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)
df = pd.read_csv('xyzr_sphere_coordinates.txt')
data = []
for index, row in df.iterrows():
(x_pns_surface, y_pns_surface, z_pns_suraface) = ms(row.x, row.y, row.z, row.r)
data.append(go.Surface(x=x_pns_surface, y=y_pns_surface, z=z_pns_suraface, opacity=0.5))
fig = go.Figure(data=data)
fig.show()
它导致这个 3d 互动人物: