Search code examples
pythonplotly-dashcytoscape

Dash_table: SyntaxError: positional argument follows keyword argument


I want to build a network using dash.

I have this data frame (called final_net):

   Entrez Gene Interactor A  Entrez Gene Interactor B
0                      6840                      7431
1                      6640                      5217
2                       823                      7431
3                     57019                     57019

If I convert that data frame to this kind of list:

dash_elements = []

for index,i in final_net.iterrows():
    dict1 = {}
    dict2 = {}
    dict1['data'] = dict2
    dict2['id'] = str(i[0])
    dict2['label'] = str(i[0])
    
    dict3 = {}
    dict1['data'] = dict3
    dict3['id'] = str(i[1])
    dict3['label'] = str(i[1])
    
    final_dict2 = {}
    final_dict3 = {}
    final_dict2['data'] = dict2
    final_dict3['data'] = dict3
    
    dash_elements.append(final_dict2)
    dash_elements.append(final_dict3)
    
  
    dict4 = {}
    final_dict4 = {}
    final_dict4['data'] = dict4
    dict4['source'] = str(i[0])
    dict4['target'] = str(i[1])
    dash_elements.append(final_dict4)
    

print(dash_elements)

And then read the data into dash like this:

import dash
import dash_core_components as dcc
from dash import html
import dash_cytoscape as cyto
from dash.dependencies import Input, Output
import plotly.express as px

app = dash.Dash(__name__)

app.layout = html.Div([
    html.P("Dash Cytoscape:"),
    cyto.Cytoscape(
        id='cytoscape',
        elements = dash_elements,
        layout={'name': 'breadthfirst'},
        style={'width': '1000px', 'height': '1000px'}
    )
])

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

A network is generated as expected.

I'm wondering if this could be done more elegantly by reading the data frame directly into the network.

I wanted to implement the answer here, so I wrote:

from dash import dash_table



dt_col_param = []
for col in final_net.columns:
    dt_col_param.append({"name": str(col), "id": str(col)})


import dash
import dash_core_components as dcc
from dash import html
import dash_cytoscape as cyto
from dash.dependencies import Input, Output
import plotly.express as px

app = dash.Dash(__name__)

app.layout = html.Div([
    html.P("Dash Cytoscape:"),
    cyto.Cytoscape(
        id='cytoscape',
        
       dash_table.DataTable(
        columns=dt_col_param,
        data=final_net.to_dict()),

        layout={'name': 'breadthfirst'},
        style={'width': '1000px', 'height': '1000px'}
    )
])

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

But it returns the error:

 File "<ipython-input-93-2fb47236fbc6>", line 31
    dash_table.DataTable(
    ^
SyntaxError: positional argument follows keyword argument

And i don't understand what I'm doing wrong. Could someone explain/show me how to correct this please?


Solution

  • Well for one, you forgot, as the error says, the keyword for the parameter (i.e., "elements"):

    app.layout = html.Div(
        [
            html.P("Dash Cytoscape:"),
            cyto.Cytoscape(
                id="cytoscape",
                elements=dash_table.DataTable(
                    columns=dt_col_param, data=final_net.to_dict()
                ),
                layout={"name": "breadthfirst"},
                style={"width": "1000px", "height": "1000px"},
            ),
        ]
    )
    
    

    But that won't quite work either because that's not valid input for elements for the cyto.Cytoscape object — which requires

    "A list of dictionaries representing the elements of the networks."

    If I have time I will come back to this & provide a more complete answer but hopefully this might be enough direction to help get you on your way to realize how to implement....