I am trying to combine two sets of nodes(ancestors and descendants) into one to draw a graph in dash. When
I Try to do this, I receive an error about a lists of lists, but the data appears to be in the correct format, which is a list of lists, nodes ahead and nodes behind of the source node
Here is the complete code
import plotly.graph_objects as go
import networkx as nx
import dash
from dash import Dash, html, dcc, Input, Output, State
import pandas as pd
# Controls for how the graph is drawn
nodeColor = 'Pink'
nodeSize = 20
lineWidth = 2
lineColor = '#000000'
df_dict = {'From': {0: 'A', 1: 'B', 2: 'C', 3: 'A', 4: 'B', 5: 'C'},
'To': {0: 'B', 1: 'C', 2: 'D', 3: 'A1', 4: 'B1', 5: 'C1'},
'weight': {0: 1.0, 1: 1.0, 2: 1.0, 3: 0.5, 4: 0.5, 5: 0.5}, 'Cost': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 2}}
df = pd.DataFrame.from_dict(df_dict)
def builddf(df):
G = nx.from_pandas_edgelist(
df, "From", 'To', ['weight', 'Cost'], create_using=nx.DiGraph())
return G
def buildGraph(G):
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 = []
text = []
for node in G.nodes():
x, y = G.nodes[node]['pos']
node_x.append(x)
node_y.append(y)
text.append(node)
edge_x = []
edge_y = []
for edge in G.edges():
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',
text=text)
node_trace = go.Scatter(x=node_x, y=node_y, text=text, mode='markers+text', 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))
)
fig.update_layout(yaxis=dict(scaleanchor="x", scaleratio=1),
plot_bgcolor='rgb(255,255,255)')
return fig
app = dash.Dash()
app.layout = html.Div([
html.Div([
html.H1(children='Hello Dash'),
html.Div(children='''
Directed Water and Orange Juice Graph.
'''),
html.Div(children=[
dcc.Dropdown([{'label': 'Connected', 'value': 'con'}, {'label': 'Ascending', 'value': 'asc'},
{'label': 'Descending', 'value': 'desc'}], '', id='typ-dropdown'),
html.Div(id='dd-typ-container'),
html.Div(html.Br()),
dcc.Dropdown(
[{'label': 'Node A', 'value': 'A'}, {'label': 'Node B', 'value': 'B'}, {'label': 'Node C', 'value': 'C'},
{'label': 'Node D', 'value': 'D'}, {'label': 'Node A1',
'value': 'A1'}, {'label': 'Node B1', 'value': 'B1'},
{'label': 'Node C1', 'value': 'C1'}], '', id='node-dropdown'),
html.Div(id='dd-out-container')
]),
html.Div([
html.H3('Water Network'),
dcc.Graph(id='example-graph1'),
], className="six columns"),
html.Div([
], className="six columns"),
], className="row")
])
@app.callback(
Output('example-graph1', 'figure'),
[Output('dd-out-container', 'children')],
[Input('typ-dropdown', 'value')],
[Input('node-dropdown', 'value')]
)
def connected_graph(contyp, value):
ddf = df.copy()
J = builddf(ddf)
fig = buildGraph(J)
if len(str(value)) > 0:
# fig = builddf(df)
asc = nx.ancestors(J, value)
desc = nx.descendants(J, value)
print('asc', asc)
print('desc', desc)
if contyp == 'desc':
_desc = list(desc)
X = 'The connected network is ' + repr(_desc)
paths = [
path for p in desc for path in nx.all_simple_paths(J, value, p)]
elif contyp == 'asc':
_asc = list(asc)
X = 'The connected network is ' + repr(_asc)
paths = [
path for p in asc for path in nx.all_simple_paths(J, p, value)]
elif contyp == 'con':
print('con')
paths = [
path for p in desc for path in nx.all_simple_paths(J, value, p)]
paths.extend(
[path for p in asc for path in nx.all_simple_paths(J, p, value)])
X = paths
else:
X = 'The length of the network is Unknown'
Q = nx.DiGraph()
for p in paths:
nx.add_path(Q, p)
figure = buildGraph(Q)
if len(paths) > 0:
return figure, X
else:
return fig, X
else:
X = 'The length of the network is not selected'
return fig, X
app.run_server(debug=True)
And selecting node A and Connected, I receive the below error
The children property of a component is a list of lists, instead of just a list. Check the
component that has the following contents, and remove one of the levels of nesting:
[
"A",
"B",
"C",
"D"
]
Hopefully there is someone around that sees what is wrong.