Sus*_*lik 3 python plotly scatter3d
我有一串球。每个球上都有一个箭头。
我想用绘图来表示上面的图形,这样我就可以旋转它,但我完全迷失了。如何将箭头定位在球上?
我开始制作前 4 个箭头,如下所示:
import plotly.graph_objs as go
import plotly
plotly.offline.init_notebook_mode()
x = [10.1219, 10.42579, 15.21396, 15.42468, 20.29639,20.46268, 25.36298, 25.49156]
y = [5.0545, 5.180104, 5.0545, 5.20337, 5.0545, 5.194271, 5.0545, 5.231627]
z = [5.2713, 5.231409, 5.2713, 5.231409, 5.2713 , 5.235852, 5.2713, 5.231627]
pairs = [(0,1), (2,3),(4,5), (6,7)]
trace1 = go.Scatter3d(
x=x,
y=y,
z=z,
mode='markers',
name='markers'
)
x_lines = list()
y_lines = list()
z_lines = list()
for p in pairs:
for i in range(2):
x_lines.append(x[p[i]])
y_lines.append(y[p[i]])
z_lines.append(z[p[i]])
x_lines.append(None)
y_lines.append(None)
z_lines.append(None)
trace2 = go.Scatter3d(
x=x_lines,
y=y_lines,
z=z_lines,
line = dict(width = 2, color = 'rgb(255, 0,0)'))
)
fig = go.Figure(data=[trace1, trace2])
plotly.offline.iplot(fig, filename='simple-3d-scatter')
Run Code Online (Sandbox Code Playgroud)
但我想要的不是连接点对的线,而是箭头。
Der*_*k O 12
我的第一个想法是,您可以使用注释来绘制箭头作为解决方法,但注释只能在 x 和 y 维度上绘制箭头,如类似问题的答案中所述。Plotly 尚未实现可以指定所有三个维度的注释箭头。
然而,@Abdul Saboor 提出了一个巧妙的技巧,即使用基本圆锥图在线段的末端绘制一个圆锥。这些参数x, y, z为您提供圆锥体底部的起始位置,并且u, v, w为您提供圆锥体指向方向的矢量场。
因此,对于每一对点,我们可以将圆锥体底部的起点设置为起始球和结束球之间的 95%,并且圆锥体的方向将是从起始点指向的向量到终点,大小可以是任何你喜欢的值,比如点之间距离的 10%,这样圆锥体就很小而且看起来很漂亮。您可以使用我设置的任意值arrow_tip_ratio来调整这些值。arrow_starting_ratio
编辑:要仅绘制起点而不绘制终点,您可以trace1通过使用列表理解仅访问每个起始球和结束球的第一个 x、y、z 坐标来进行修改。然后,您应该指定 的参数mode='lines',以便trace2仅在每个起点和终点的第一个点上绘制线条。
import plotly.graph_objs as go
# plotly.offline.init_notebook_mode()
x = [10.1219, 10.42579, 15.21396, 15.42468, 20.29639,20.46268, 25.36298, 25.49156]
y = [5.0545, 5.180104, 5.0545, 5.20337, 5.0545, 5.194271, 5.0545, 5.231627]
z = [5.2713, 5.231409, 5.2713, 5.231409, 5.2713 , 5.235852, 5.2713, 5.231627]
pairs = [(0,1), (2,3),(4,5), (6,7)]
## plot ONLY the first ball in each pair of balls
trace1 = go.Scatter3d(
x=[x[p[0]] for p in pairs],
y=[y[p[0]] for p in pairs],
z=[z[p[0]] for p in pairs],
mode='markers',
name='markers',
line=dict(color='red')
)
x_lines = list()
y_lines = list()
z_lines = list()
for p in pairs:
for i in range(2):
x_lines.append(x[p[i]])
y_lines.append(y[p[i]])
z_lines.append(z[p[i]])
x_lines.append(None)
y_lines.append(None)
z_lines.append(None)
## set the mode to lines to plot only the lines and not the balls/markers
trace2 = go.Scatter3d(
x=x_lines,
y=y_lines,
z=z_lines,
mode='lines',
line = dict(width = 2, color = 'rgb(255, 0,0)')
)
fig = go.Figure(data=[trace1, trace2])
arrow_tip_ratio = 0.1
arrow_starting_ratio = 0.98
## the cone will point in the direction of vector field u, v, w
## so we take this to be the difference between each pair
## then hack the colorscale to force it to display the same color
## by setting the starting and ending colors to be the same
for p in pairs:
fig.add_trace(go.Cone(
x=[x[p[0]] + arrow_starting_ratio*(x[p[1]] - x[p[0]])],
y=[y[p[0]] + arrow_starting_ratio*(y[p[1]] - y[p[0]])],
z=[z[p[0]] + arrow_starting_ratio*(z[p[1]] - z[p[0]])],
u=[arrow_tip_ratio*(x[p[1]] - x[p[0]])],
v=[arrow_tip_ratio*(y[p[1]] - y[p[0]])],
w=[arrow_tip_ratio*(z[p[1]] - z[p[0]])],
showlegend=False,
showscale=False,
colorscale=[[0, 'rgb(255,0,0)'], [1, 'rgb(255,0,0)']]
))
fig.show()
# plotly.offline.iplot(fig, filename='simple-3d-scatter')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6063 次 |
| 最近记录: |