免责声明:我在plotly github上添加了一个功能请求,以获取与我正在寻找的功能类似的功能。
我写了一段代码,使用plotly绘制向量场,类似于3D中的锥体图,以下是代码片段:
import numpy as np
import plotly.graph_objects as go
import plotly.colors as pc
def plot_vector_field(x,y,u,v):
# Function to get colors for the triangles
def get_colors(values, colorscale='Viridis'):
colorscale = pc.get_colorscale(colorscale)
unique_magnitudes = np.unique(values)
color_map = {val: pc.sample_colorscale(colorscale, val)[0] for val in unique_magnitudes}
return np.vectorize(color_map.get)(values)
# Function to plot the triangles
def plot_triangle(fig, position,direction,size,color):
x = [position[0]+direction[0]*size/2,
position[0]-direction[0]*size/3 + direction[1]*size/4,
position[0]-direction[0]*size/3 - direction[1]*size/4]
y = [position[1]+direction[1]*size/2,
position[1]-direction[1]*size/3 - direction[0]*size/4,
position[1]-direction[1]*size/3 + direction[0]*size/4]
fig.add_trace(go.Scatter(
x=x,
y=y,
fill='toself',
mode='lines',
line=dict(color='rgba(0,0,0,0)'),
fillcolor=color,
showlegend=False,
name=''
))
# Calculate the magnitude of the vectors
magnitude = np.sqrt(u**2 + v**2)
magnitude_normalized = magnitude/np.max(magnitude)
# Get the colors for the triangles
colors = get_colors(magnitude_normalized, colorscale='viridis')
# Get the direction of the vectors
angle = np.arctan2(v, u)
direction = np.array([np.cos(angle), np.sin(angle)]).T
# Create the figure
fig = go.Figure()
# For each point in the grid, plot a triangle
for i in range(len(x)):
plot_triangle(fig,
position=[x[i],y[i]],
direction=direction[i],
size=0.8*magnitude_normalized[i],
color=colors[i])
# Add a trace for the colorbar
colorbar_trace = go.Scatter(
x=[None],
y=[None],
mode='markers',
marker=dict(
colorscale='Viridis',
cmin=0,
cmax=np.max(magnitude),
colorbar=dict(
title=''
)
),
showlegend=False
)
fig.add_trace(colorbar_trace)
return fig
x = np.linspace(-2, 2, 10)
y = np.linspace(-2, 2, 10)
X, Y = np.meshgrid(x, y)
u = -1 - X**2 + Y
v = 1 + X - Y**2
fig = plot_vector_field(X.flatten(), Y.flatten(), u.flatten(), v.flatten())
fig.show()
问题是,当我扩大点数时,该函数的性能很差,因为它将每个三角形绘制为不同的轨迹。
有更好的方法吗?
我已经研究过在一条轨迹中绘制所有三角形,但发现很难使填充和颜色按预期工作。
我实际上自己找到了方法,通过使用分散函数来代替。这是一个可以实现这一目的的功能脚本:
import plotly.graph_objects as go
import numpy as np
x = np.linspace(-2, 2, 10)
y = np.linspace(-2, 2, 10)
X, Y = np.meshgrid(x, y)
u = -1 - X**2 + Y
v = 1 + X - Y**2
# Calculate the magnitude of the vectors
magnitude = np.sqrt(u**2 + v**2)
magnitude_normalized = magnitude/np.max(magnitude)
# Get the direction of the vectors
angle = np.arctan2(v, u)
direction = np.array([np.cos(angle), np.sin(angle)]).T
fig = go.Figure(data = go.Scatter(
x=X.flatten(),
y=Y.flatten(),
mode='markers',
marker=dict(symbol='arrow', angle=angle.flatten()*180/np.pi, size=50*magnitude_normalized.flatten(), color=magnitude_normalized.flatten())
)
)
fig.show()