Animate the width of a line inside a network graph

Hi I am very new to plotly. I have a network but I would like to animate the line on one of the edges to grow based on a list of values. I am not sure how to do that.
Below is the code I have:

`from dash import Dash, html
import dash_cytoscape as cyto

app = Dash(name)

directed_edges = [
{‘data’: {‘id’: src+tgt, ‘source’: src, ‘target’: tgt, ‘weight’: 7}}
for src, tgt in [‘BA’, ‘BC’, ‘CD’, ‘DA’, ‘AD’]
]

directed_elements = [{‘data’: {‘id’: id_}} for id_ in ‘ABCD’] + directed_edges

app.layout = html.Div([
cyto.Cytoscape(
id=‘cytoscape-styling-9’,
layout={‘name’: ‘circle’},
style={‘width’: ‘100%’, ‘height’: ‘400px’},
elements=directed_elements,
stylesheet=[
{
‘selector’: ‘node’,
‘style’: {
‘label’: ‘data(id)’
}
},
{
‘selector’: ‘edge’,
‘style’: {
# The default curve style does not work with certain arrows
‘curve-style’: ‘bezier’
}
},
{
‘selector’: ‘#BA’,
‘style’: {
‘source-arrow-color’: ‘red’,
‘source-arrow-shape’: ‘triangle’,
‘line-color’: ‘red’
}
},
{
‘selector’: ‘#DA’,
‘style’: {
‘target-arrow-color’: ‘blue’,
‘target-arrow-shape’: ‘triangle’,
‘line-color’: ‘blue’
}
},
{
‘selector’: ‘#AD’,
‘style’: {
‘target-arrow-color’: ‘magenta’,
‘target-arrow-shape’: ‘triangle’,
‘line-color’: ‘magenta’
}
},
{
‘selector’: ‘#BC’,
‘style’: {
‘source-arrow-color’: ‘green’,
‘source-arrow-shape’: ‘triangle’,
‘line-color’: ‘green’,
}
},
{
‘selector’: ‘#CD’,
‘style’: {
‘target-arrow-color’: ‘black’,
‘target-arrow-shape’: ‘triangle’,
‘line-color’: ‘black’,
‘width’: 15,
}
}
]
)
])

if name == ‘main’:
app.run(debug=True)
~

1 Like

Hi @surendraa ,

Welcome to the forum!

Since you are using Dash, you can create Drop down and set callback fucntion to update the the stylesheet of the Cytoscape by setting width value dynamically.
I assume that the width of the edge same as the weight value, so the width can be use to size width of the edge.

And if I implement it, the display maybe like below.
network_cytoscape3

is this what you mean ?

1 Like

Thank you for this reply. This is similar to what I want. I would like to animate it without the dropdown. Do you have an example code or a link to documentation that might help?

Hi @surendraa ,

If you want to perform animation using cyoscape and dash callback, you can replace the dcc.Dropdown with dcc.Interval.

Set Interval value in miliseconds.
Then create callback function use Internal component as Input and Cytoscape component as `Output.

For example you want to animate the edge with red color with interval 1 second.

from dash import Dash, html,dcc,Input,Output,State
import dash_cytoscape as cyto

app = Dash(__name__)

edge_ids = ['BA', 'BC', 'CD', 'DA', 'AD']

directed_edges = [{'data': {'id': src+tgt, 'source': src, 'target': tgt, 'weight': 3}} for src, tgt in edge_ids]

directed_elements = [{'data': {'id': id_}} for id_ in 'ABCD'] + directed_edges

default_stylesheet = [
                {
                    'selector': 'node',
                    'style': {
                        'label': 'data(id)'
                    }
                },
                {
                    'selector': 'edge',
                    'style': {
                        # The default curve style does not work with certain arrows
                        'curve-style': 'bezier'
                    }
                },
                {
                    'selector': '#BA',
                    'style': {
                        'source-arrow-color': 'red',
                        'source-arrow-shape': 'triangle',
                        'line-color': 'red',
                        'width':3,
                    }
                },
                {
                'selector': '#DA',
                'style': {
                        'target-arrow-color': 'blue',
                        'target-arrow-shape': 'triangle',
                        'line-color': 'blue',
                        'width':3,
                    }
                },
                {
                    'selector': '#AD',
                    'style': {
                        'target-arrow-color': 'magenta',
                        'target-arrow-shape': 'triangle',
                        'line-color': 'magenta',
                        'width':3,
                    }
                },
                {
                    'selector': '#BC',
                    'style': {
                        'source-arrow-color': 'green',
                        'source-arrow-shape': 'triangle',
                        'line-color': 'green',
                        'width':3,
                    }
                },
                {
                    'selector': '#CD',
                    'style': {
                        'target-arrow-color': 'black',
                        'target-arrow-shape': 'triangle',
                        'line-color': 'black',
                        'width':3,
                    }
                }
            ]

selectors = [data["selector"] for data in default_stylesheet]

width_list = list(range(3,21,2))

app.layout = html.Div([
        dcc.Interval(id="interval", interval=1000),
        html.Div([
            cyto.Cytoscape(
                id='cytoscape-styling-9',
                layout={'name': 'circle','animate':True,'animationDuration': 500},
                style={'width': '100%', 'height': '400px'},
                elements=directed_elements,
                stylesheet=default_stylesheet
            )
        ])
    ])

@app.callback(
    Output("cytoscape-styling-9","stylesheet"),
    [Input('interval', 'n_intervals')],
    prevent_initial_call=True
    )
def update_weight_value(n_intervals):
    current_index = width_list.index(default_stylesheet[2]['style']['width']) 
    if current_index < len(width_list)-1:
        default_stylesheet[2]['style']['width'] = width_list[current_index+1]
        
    else:
        default_stylesheet[2]['style']['width'] = width_list[0]
    return default_stylesheet


if __name__ == '__main__':
    app.run(debug=True)

It will be displayed like image below.

network_callback_animation

Hope this is solution you are looking for.
Cheers. :slightly_smiling_face:

2 Likes

Thank you so much. This has helped me understand the callback and how to change the css.