python - 在 plotly 上将滑块添加到有向加权图
问题描述
我想在plotly
使用时绘制一个带有边权重的有向图python
。最重要的是,我想添加一个滑块来对要显示的边缘进行一些阈值处理。一个简单的例子:一个有 2 个点的滑块,在第一个点上,滑块将显示所有边缘,而在第二个点上,滑块将只显示权重 > 0.5 的边缘。这只是一个简单的示例,我想将其扩展为滑块上有 10 个点(意味着 10 个不同的阈值)。
我遇到的问题是,为了可视化有向边,我为每条边绘制了一条轨迹,以便能够将轨迹的不透明度设置为相应的边权重。我还在边缘添加了一些悬停文本。所以我的绘图上有很多痕迹,1 表示节点,X 表示边缘(其中 X 是边数),X 表示边缘悬停。如何配置滑块以执行此阈值以提高可见性?
我的想法是为每个跟踪设置一个 id,将特定边缘所属的“滑块点”上下文化,但这似乎不起作用。下面是我的代码。任何帮助表示赞赏!谢谢!
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import plotly.graph_objects as go
from tqdm import tqdm
G = nx.DiGraph()
edges = [(1,2), (2,4), (4,0), (5,1)]
edge_weights = {(1,2): 0.1, (2,4): 0.5, (4,0): 1, (5,1): 0.3}
node_weights = [0.1, 0.2, 0.3, 0.4, 0.5]
G.add_edges_from(edges)
pos = nx.spring_layout(G, k=10) # For better example looking
# Plot nodes with go.Scatter
node_x = []
node_y = []
for node in G.nodes():
x, y = pos[node]
node_x.append(x)
node_y.append(y)
traces = []
node_trace = go.Scatter(
x=node_x, y=node_y, visible=True,
marker=dict(
showscale=True, color=node_weights,
colorbar=dict(
thickness=15,
title='Node weights',
xanchor='left',
titleside='right'
),
line_width=2))
traces.append(node_trace)
#Get edge trace IDs for slider filtering
edge_trace_ids = {}
for w in edge_weights:
if w <= 0.5:
edge_trace_ids[w] = 0
else:
edge_trace_ids[w] = 1
x0, y0, x1, y1 = [], [], [], []
i=0
for edge,weight in tqdm(zip(edges,edge_weights)):
# Get the coordinates of each node
edge_coord_source = pos[edge[0]]
edge_coord_target = pos[edge[1]]
x0.append(edge_coord_source[0])
y0.append(edge_coord_source[1])
x1.append(edge_coord_target[0])
y1.append(edge_coord_target[1])
# Plot edges hover with go.Scatter.
middle_hover_trace = go.Scatter(
x=[], y=[], hovertext=[], mode='markers', hoverinfo="text",
marker={'size': 20, 'color': 'LightSkyBlue'}, opacity=0,
visible=False,
uid=edge_trace_ids[weight] #my attempt to assign ID for each trace for slider filtering
)
middle_hover_trace['x'] = tuple([(edge_coord_source[0] + edge_coord_target[0]) / 2])
middle_hover_trace['y'] = tuple([(edge_coord_source[1] + edge_coord_target[1]) / 2])
hovertext = f"Edge weight: {weight}"
middle_hover_trace['hovertext'] = tuple([hovertext])
traces.append(middle_hover_trace)
# Plot edges with go.Scatter.
# This has to be done in a loop to be able to set the opacity/color according to weights
edge_trace = go.Scatter(
x=tuple([edge_coord_source[0], edge_coord_target[0], None]),
y=tuple([edge_coord_source[1], edge_coord_target[1], None]),
mode='lines',
marker=dict(color="red"),
line_shape='spline',
opacity=weight,
visible=False,
uid=edge_trace_ids[weight]
)
traces.append(edge_trace)
i+=1
fig = go.Figure(
data = traces,
layout=go.Layout(
title=dict(text="Directed Graph", font=dict(size=14, color='blue')),
showlegend=False,
margin=dict(b=20,l=5,r=5,t=40),
annotations = [
dict(
ax=x0[i], ay=y0[i], axref='x', ayref='y',
x=x1[i], y=y1[i], xref='x', yref='y',
showarrow=True, arrowhead=1, arrowsize=2,
arrowcolor="red" if w == 1 else "green",
opacity=w/3, visible=False, name=edge_trace_ids[w]
)
for i,w in enumerate(edge_weights)
],
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
)
)
# Create and add slider
sliders_steps = 2
steps = []
for i in range(sliders_steps):
step = dict(
method="update",
args=[{"visible": [False] * sliders_steps},
{"title": "Slider switched to step: " + str(i)}], # layout attribute
)
for fig_data in fig.data:
if int(fig_data.uid) == i:
fig_data.visible = True
step["args"][0]["visible"][i] = True # Toggle i'th trace to "visible"
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "Frequency: "},
pad={"t": 50},
steps=steps
)]
fig.update_layout(sliders=sliders)
解决方案
推荐阅读
- c - 使用c中的链表进行中缀到后缀转换
- javascript - 如何对从 API 获取的数据进行搜索过滤
- swift - HKWorkoutSession 没有完成?
- reactjs - FabricJS 对象在左上角不可选择/可点击/调整大小(React + FabricJs)
- r - 基于 RStudio 中的一个日期列格式化多个时间列
- wpf - 使用 Prism 在第二台显示器上显示 wpf 窗口
- xml - Dataweave 2.0 - 如何根据属性名称获取 XML 元素值
- azure - Azure 数据工厂在插入数据库之前合并到文件
- python - 如何将 Plotly 图形工厂注释的热图添加到 PDF 而不看起来模糊?
- python - 如何在 3D 图上绘制直方图?