Monday, 6 February 2023

Plotly Dash change networkx node colours in based on user input?

After creating the minimal working example below, I tried to change the color of the nodes in the graphs based on user input. Specifically, I have n lists of colors (one color per node), and I would like the user to be able to loop (ideally forward and backwards) through the node color lists. (In essence I show firing neurons using the color).

MWE

"""Generates a graph in dash."""


import dash
import dash_core_components as dcc
import dash_html_components as html
import networkx as nx
import plotly.graph_objs as go

# Create graph G
G = nx.DiGraph()
G.add_nodes_from([0, 1, 2])
G.add_edges_from(
    [
        (0, 1),
        (0, 2),
    ],
    weight=6,
)

# Create a x,y position for each node
pos = {
    0: [0, 0],
    1: [1, 2],
    2: [2, 0],
}
# Set the position attribute with the created positions.
for node in G.nodes:
    G.nodes[node]["pos"] = list(pos[node])

# add color to node points
colour_set_I = ["rgb(31, 119, 180)", "rgb(255, 127, 14)", "rgb(44, 160, 44)"]
colour_set_II = ["rgb(10, 20, 30)", "rgb(255, 255, 0)", "rgb(0, 255, 255)"]

# Create nodes
node_trace = go.Scatter(
    x=[],
    y=[],
    text=[],
    mode="markers",
    hoverinfo="text",
    marker=dict(size=30, color=colour_set_I),
)

for node in G.nodes():
    x, y = G.nodes[node]["pos"]
    node_trace["x"] += tuple([x])
    node_trace["y"] += tuple([y])


# Create Edges
edge_trace = go.Scatter(
    x=[],
    y=[],
    line=dict(width=0.5, color="#888"),
    hoverinfo="none",
    mode="lines",
)

for edge in G.edges():
    x0, y0 = G.nodes[edge[0]]["pos"]
    x1, y1 = G.nodes[edge[1]]["pos"]
    edge_trace["x"] += tuple([x0, x1, None])
    edge_trace["y"] += tuple([y0, y1, None])

################### START OF DASH APP ###################
app = dash.Dash()


fig = go.Figure(
    data=[edge_trace, node_trace],
    layout=go.Layout(
        xaxis=dict(showgrid=True, zeroline=True, showticklabels=True),
        yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
    ),
)

app.layout = html.Div(
    [
        html.Div(dcc.Graph(id="Graph", figure=fig)),
    ]
)

if __name__ == "__main__":
    app.run_server(debug=True)

When you save this as graph.py and run it with: python graph.py, you can open a browser, go to 127.0.0.1:8050 and see: enter image description here For colour_set_I, and: enter image description here For colour_set_II.

Question

How can I get a slider e.g. from 0 to n or a next> and back< button that loads the next/previous colour list into the nodes?

Hacky

I noticed when I change the graph.py file line:

marker=dict(size=30, color=colour_set_I),

to:

marker=dict(size=30, color=colour_set_II),

it automatically updates the node colors, however, typing the frame index into the colour set and pressing ctrl+s is somewhat elaborate, even though I thoroughly enjoy keyboard control over clicking.



from Plotly Dash change networkx node colours in based on user input?

No comments:

Post a Comment