Reputation: 1958
It seems Dash is unable to process directed network graphs via plotly. So I am going through Matplotlib to render the graph using mpl_to_plotly. A graph does render on the site, but without the edges, and there is the following console output:
Dang! That path collection is out of this world. I totally don't know what to do with it yet! Plotly can only import path collections linked to 'data' coordinates
Matplotlib code
mpl_fig , ax = plt.subplots()
G = nx.Graph()
G.add_edge('a', 'b', weight=0.6)
G.add_edge('a', 'c', weight=0.2)
G.add_edge('c', 'd', weight=0.1)
G.add_edge('c', 'e', weight=0.7)
G.add_edge('c', 'f', weight=0.9)
G.add_edge('a', 'd', weight=0.3)
elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5]
esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5]
pos = nx.spring_layout(G) # positions for all nodes
# nodes
nx.draw_networkx_nodes(G, pos, node_size=700)
# edges
nx.draw_networkx_edges(G, pos, edgelist=elarge,
width=6)
nx.draw_networkx_edges(G, pos, edgelist=esmall,
width=6, alpha=0.5, edge_color='b', style='dashed')
# labels
nx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif')
# error with plotly no supporting this kind of thing. Ty exporting to image and just show the image. Sucks becaues it is not interactive... but at least im showing what I want.
print(pos)
#plt.show()
plotly_fig = mpl_to_plotly(mpl_fig)
called in Dash via
dcc.Graph(id='network-graph', figure=plotly_fig)
Is there another method to process network directed graphs in Dash? Or another way to use the matplotlib technique?
Upvotes: 1
Views: 2222
Reputation: 8962
There is an opened issue in Plotly that mpl_to_ploty
doesn't work with draw_networkx_edges
(link).
Also Plotly doesn't natively support directed edges (link), they might be simulated with arrows from annotations though.
Given that graph figure might be constructed manually with Plotly syntax, e.g. as (without Matplotlib):
import networkx as nx
import dash
import dash_core_components as dcc
import dash_html_components as html
G = nx.DiGraph()
G.add_edge('a', 'b', weight=0.6)
G.add_edge('a', 'c', weight=0.2)
G.add_edge('c', 'd', weight=0.1)
G.add_edge('c', 'e', weight=0.7)
G.add_edge('c', 'f', weight=0.9)
G.add_edge('a', 'd', weight=0.3)
elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5]
esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5]
pos = nx.spring_layout(G) # positions for all nodes
Xn=[pos[k][0] for k in pos]
Yn=[pos[k][1] for k in pos]
labels = [k for k in pos]
nodes=dict(type='scatter',
x=Xn,
y=Yn,
mode='markers+text',
marker=dict(size=28, color='rgb(31,120,180)'),
textfont=dict(size=22, color='#DBD700'),
text=labels,
hoverinfo='text')
Xaxis=dict(showline=False, zeroline=False, showgrid=False, showticklabels=True,
mirror='allticks', ticks='inside', ticklen=5, tickfont = dict(size=14),
title='')
Yaxis=dict(showline=False, zeroline=False, showgrid=False, showticklabels=True,
mirror='allticks', ticks='inside', ticklen=5, tickfont = dict(size=14),
title='')
annotateELarge = [ dict(showarrow=True, arrowsize=0.9, arrowwidth=6, arrowhead=5, standoff=14, startstandoff=4,
ax=pos[arrow[0]][0], ay=pos[arrow[0]][1], axref='x', ayref='y',
x=pos[arrow[1]][0], y=pos[arrow[1]][1], xref='x', yref='y'
) for arrow in elarge]
annotateESmall = [ dict(showarrow=True, arrowsize=1.5, arrowwidth=2, arrowhead=5, opacity=0.5, standoff=14, startstandoff=4,
ax=pos[arrow[0]][0], ay=pos[arrow[0]][1], axref='x', ayref='y',
x=pos[arrow[1]][0], y=pos[arrow[1]][1], xref='x', yref='y'
) for arrow in esmall]
layout=dict(width=800, height=600,
showlegend=False,
xaxis=Xaxis,
yaxis=Yaxis,
hovermode='closest',
plot_bgcolor='#E5ECF6',
annotations= annotateELarge + annotateESmall, #arrows
)
plotly_fig = dict(data=[nodes], layout=layout)
#Dash page stub
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(children=[
dcc.Graph(id='network-graph', figure=plotly_fig)
])
if __name__ == '__main__':
app.run_server(debug=True)
Upvotes: 2