Cytoscape node position not working

Hello,
I’ve been trying to use Cytoscape and assign position to every node, but doesn’t seems to work. Even if I copy the example from the documentation:

import dash_cytoscape as cyto
import dash_html_components as html

app = dash.Dash(__name__)
app.layout = html.Div([
    cyto.Cytoscape(
        id='cytoscape',
        elements=[
            {'data': {'id': 'one', 'label': 'Node 1'}, 'position': {'x': 50, 'y': 50}},
            {'data': {'id': 'two', 'label': 'Node 2'}, 'position': {'x': 200, 'y': 200}},
            {'data': {'source': 'one', 'target': 'two','label': 'Node 1 to 2'}}
        ],
        layout={'name': 'preset'}
    )
])

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

Any idea how to achieve this?

Hi @luquezsantiago, using your code the positioning of the nodes works just fine. The x and y coordinates are relative to the figure’s origin (where (x,y) = (0,0)). But the position of the origin is not fixed, it’s dynamically positioned to make sure that your network of nodes is centered in the cytoscape, hopefully the screenshots below will help:

Here you can see that the origin is not at the top left corner as we could have expected, its position makes sure that the whole network is centered. If you wish to place a node to the right of the origin then your x value should be positive (and negative to place it on the left). If you wish to place a node above the origin then your y value should be negative (and positive to place it below).

With different coordinates for nodes, the origin also has a different position:

All this is happens because of the 'fit' : True default parameter in the layout that fits the cytoscape to the viewport.
If you add 'fit' : False in your layout then the origin will always be fixed on the top left corner and you can place your nodes relative to that origin:

Here's the code of that last screenshot
from dash import Dash, html
import dash_cytoscape as cyto

app = Dash(__name__)
app.layout = html.Div([
    cyto.Cytoscape(
        id='cytoscape',
        style={'width': '500px', 'height': '500px', 'backgroundColor': '#a3c3f7'},
        elements=[
            {'data': {'id': 'one', 'label': 'Node 1 (150, 80)'}, 'position': {'x': 150, 'y': 80}},
            {'data': {'id': 'three', 'label': 'Origin (0,0)'}, 'position': {'x': 0, 'y': 0}},
            {'data': {'id': 'two', 'label': 'Node 2 (270, 400)'}, 'position': {'x': 270, 'y': 400}},
            {'data': {'source': 'one', 'target': 'two','label': 'Node 1 to 2'}}
        ],
        stylesheet=[
        # Group selectors
        {
            'selector': 'node',
            'style': {
                'content': 'data(label)',
                'text-halign':'right',
                'text-valign':'bottom'
            }
        },],
        layout={'name': 'preset',
                'fit': False}
    )
])

if __name__ == '__main__':
    app.run_server(debug=True, use_reloader=True)

Hope that helps.

3 Likes

Thanks so much! I don’t know why it was not working.