为了构建有向网络图,Plotly当前的方法似乎是使用注释。当边缘很少且一个人可以通过图形布局手动填充每个人时,例如this example,这种方法就可以使用。
但是,如果我要创建一个更为复杂的图形,是否有一种很好的方法来迭代定义所有边缘的箭头坐标(我只能想到构造一个字符串然后使用eval()
,尽管我知道这是不好的做法)? (编辑:这种将迭代生成的dict()
定义字符串进行级联的方法似乎不起作用-仅适用于一个dict()
定义)
编辑:添加代码段以更好地说明这种情况(将eval()
行注释掉以进行比较):
import plotly.offline as py
import plotly.graph_objs as go
trace = go.Scatter(
x=[1, 2, 2, 1],
y=[3, 4, 3, 4],
mode='markers',
marker=dict(size=[100, 100, 100, 100])
)
fig = go.Figure(
data=[trace],
layout=go.Layout(
annotations = [
dict(
ax=1, ay=3, axref='x', ayref='y',
x=2, y=4, xref='x', yref='y'
),
# eval("dict(ax=2, ay=3, axref='x', ayref='y', x=1, y=4, xref='x', yref='y')")
]
)
)
py.plot(fig)
如果有在Bokeh或其他人的帮助下进行可视化的好方法,我也愿意尝试其他可视化程序包。
答案 0 :(得分:3)
下面是使用循环在Plotly图中创建箭头的示例,该示例很容易适用于NetworkX有向图的可视化。
import plotly.offline as py
import plotly.graph_objs as go
trace = go.Scatter(
x=[1, 2, 2, 1],
y=[3, 4, 3, 4],
mode='markers',
marker=dict(size=[100, 100, 100, 100])
)
# Edges
x0 = [1, 2]
y0 = [3, 3]
x1 = [2, 1]
y1 = [4, 4]
fig = go.Figure(
data=[trace],
layout=go.Layout(
annotations = [
dict(ax=x0[i], ay=y0[i], axref='x', ayref='y',
x=x1[i], y=y1[i], xref='x', yref='y') for i in range(0, len(x0))
]
)
)
py.plot(fig)
答案 1 :(得分:1)
是的,我同意注释解决方案的效率不高。这对您尝试做的事情有用吗:https://github.com/redransil/plotly-dirgraph
import plotly.graph_objects as go
import networkx as nx
import dash
import dash_core_components as dcc
import dash_html_components as html
from addEdge import addEdge
# Controls for how the graph is drawn
nodeColor = 'Blue'
nodeSize = 20
lineWidth = 2
lineColor = '#000000'
# Make a random graph using networkx
G = nx.random_geometric_graph(5, .5)
pos = nx.layout.spring_layout(G)
for node in G.nodes:
G.nodes[node]['pos'] = list(pos[node])
# Make list of nodes for plotly
node_x = []
node_y = []
for node in G.nodes():
x, y = G.nodes[node]['pos']
node_x.append(x)
node_y.append(y)
# Make a list of edges for plotly, including line segments that result in arrowheads
edge_x = []
edge_y = []
for edge in G.edges():
# addEdge(start, end, edge_x, edge_y, lengthFrac=1, arrowPos = None, arrowLength=0.025, arrowAngle = 30, dotSize=20)
start = G.nodes[edge[0]]['pos']
end = G.nodes[edge[1]]['pos']
edge_x, edge_y = addEdge(start, end, edge_x, edge_y, .8, 'end', .04, 30, nodeSize)
edge_trace = go.Scatter(x=edge_x, y=edge_y, line=dict(width=lineWidth, color=lineColor), hoverinfo='none', mode='lines')
node_trace = go.Scatter(x=node_x, y=node_y, mode='markers', hoverinfo='text', marker=dict(showscale=False, color = nodeColor, size=nodeSize))
fig = go.Figure(data=[edge_trace, node_trace],
layout=go.Layout(
showlegend=False,
hovermode='closest',
margin=dict(b=20,l=5,r=5,t=40),
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
)
# Note: if you don't use fixed ratio axes, the arrows won't be symmetrical
fig.update_layout(yaxis = dict(scaleanchor = "x", scaleratio = 1), plot_bgcolor='rgb(255,255,255)')
app = dash.Dash()
app.layout = html.Div([dcc.Graph(figure=fig)])
app.run_server(debug=True, use_reloader=False)
答案 2 :(得分:0)
可以使用库d3graph
。您可以指定有向边。这是一个受力控制的d3图。更多信息发布在这里:Django and interactive graph/network visualization