Black Lives Matter. Please consider donating to Black Girls Code today.

Dash Data-table arguments do not work

Hi,

I’m trying to use the code below which is provided in the dash datatable documentation. However, it doesn’t work and i get the unexpected keyword argument error for multiple arguments. Is it because of version error ? Please help.

import dash
from dash.dependencies import Input, Output
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

df = pd.read_csv(‘https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv’)

app = dash.Dash(name)

app.layout = html.Div([
dash_table.DataTable(
id=‘datatable-interactivity’,
columns=[
{“name”: i, “id”: i, “deletable”: True, “selectable”: True} for i in df.columns
],
data=df.to_dict(‘records’),
editable=True,
filter_action=“native”,
sort_action=“native”,
sort_mode=“multi”,
column_selectable=“single”,
row_selectable=“multi”,
row_deletable=True,
selected_columns=[],
selected_rows=[],
page_action=“native”,
page_current= 0,
page_size= 10,
),
html.Div(id=‘datatable-interactivity-container’)
])

@app.callback(
Output(‘datatable-interactivity’, ‘style_data_conditional’),
[Input(‘datatable-interactivity’, ‘selected_columns’)]
)
def update_styles(selected_columns):
return [{
‘if’: { ‘column_id’: i },
‘background_color’: ‘#D2F3FF
} for i in selected_columns]

@app.callback(
Output(‘datatable-interactivity-container’, “children”),
[Input(‘datatable-interactivity’, “derived_virtual_data”),
Input(‘datatable-interactivity’, “derived_virtual_selected_rows”)])
def update_graphs(rows, derived_virtual_selected_rows):
# When the table is first rendered, derived_virtual_data and
# derived_virtual_selected_rows will be None. This is due to an
# idiosyncracy in Dash (unsupplied properties are always None and Dash
# calls the dependent callbacks when the component is first rendered).
# So, if rows is None, then the component was just rendered
# and its value will be the same as the component’s dataframe.
# Instead of setting None in here, you could also set
# derived_virtual_data=df.to_rows('dict') when you initialize
# the component.
if derived_virtual_selected_rows is None:
derived_virtual_selected_rows = []

dff = df if rows is None else pd.DataFrame(rows)

colors = ['#7FDBFF' if i in derived_virtual_selected_rows else '#0074D9'
          for i in range(len(dff))]

return [
    dcc.Graph(
        id=column,
        figure={
            "data": [
                {
                    "x": dff["country"],
                    "y": dff[column],
                    "type": "bar",
                    "marker": {"color": colors},
                }
            ],
            "layout": {
                "xaxis": {"automargin": True},
                "yaxis": {
                    "automargin": True,
                    "title": {"text": column}
                },
                "height": 250,
                "margin": {"t": 10, "l": 10, "r": 10},
            },
        },
    )
    # check if column exists - user may have deleted it
    # If `column.deletable=False`, then you don't
    # need to do this check.
    for column in ["pop", "lifeExp", "gdpPercap"] if column in dff
]

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

Here is the errors I receive after running your code:

Traceback (most recent call last):

dash.exceptions.NonExistentIdException: 
                            Attempting to assign a callback to the
                            component with the id "datatable - interactivity - container" but no
                            components with id "datatable - interactivity - container" exist in the
                            app's layout.


                            Here is a list of IDs in layout:
['datatable - interactivity', 'datatable-interactivity-container']


                            If you are assigning callbacks to components
                            that are generated by other callbacks
                            (and therefore not in the initial layout), then
                            you can suppress this exception by setting
                            `suppress_callback_exceptions=True`.

So the problems are in your use of spaces in the component ID’s. Removing spaces in your id names also fixes a CSS error I received.

Here is the corrected code:

import dash
from dash.dependencies import Input, Output
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')

app = dash.Dash(__name__)

app.layout = html.Div([
    dash_table.DataTable(
        id='datatable-interactivity',
        columns=[
            {'name': i, 'id': i, 'deletable': True, 'selectable': True} for i in df.columns
        ],
        data=df.to_dict('records'),
        editable=True,
        filter_action='native',
        sort_action='native',
        sort_mode='multi',
        column_selectable='single',
        row_selectable='multi',
        row_deletable=True,
        selected_columns=[],
        selected_rows=[],
        page_action='native',
        page_current=0,
        page_size=10,
    ),
    html.Div(id='datatable-interactivity-container')
])


@app.callback(Output('datatable-interactivity', 'style_data_conditional'),
    [Input('datatable-interactivity', 'selected_columns')]
)
def update_styles(selected_columns):
    return [{
        'if ': {'column_id': i},
        'background_color': '  # D2F3FF'
    } for i in selected_columns]


@app.callback(
    Output('datatable-interactivity-container', 'children'),
    [Input('datatable-interactivity', 'derived_virtual_data'),
     Input('datatable-interactivity', 'derived_virtual_selected_rows')])
def update_graphs(rows, derived_virtual_selected_rows):
    # When the table is first rendered, derived_virtual_data and
    # derived_virtual_selected_rows will be None. This is due to an
    # idiosyncracy in Dash (unsupplied properties are always None and Dash
    # calls the dependent callbacks when the component is first rendered).
    # So, if rows is None, then the component was just rendered
    # and its value will be the same as the component's dataframe.
    # Instead of setting None in here, you could also set
    # derived_virtual_data=df.to_rows('dict') when you initialize
    # the component.
    if derived_virtual_selected_rows is None:
        derived_virtual_selected_rows = []

    dff = df if rows is None else pd.DataFrame(rows)

    colors = ['#7FDBFF' if i in derived_virtual_selected_rows else '#0074D9'
              for i in range(len(dff))]

    return [
        dcc.Graph(
            id=column,
            figure={
                "data": [
                    {
                        "x": dff["country"],
                        "y": dff[column],
                        "type": "bar",
                        "marker": {"color": colors},
                    }
                ],
                "layout": {
                    "xaxis": {"automargin": True},
                    "yaxis": {
                        "automargin": True,
                        "title": {"text": column}
                    },
                    "height": 250,
                    "margin": {"t": 10, "l": 10, "r": 10},
                },
            },
        )
        # check if column exists - user may have deleted it
        # If `column.deletable=False`, then you don't
        # need to do this check.
        for column in ["pop", "lifeExp", "gdpPercap"] if column in dff
    ]
if __name__ == '__main__':
    app.run_server(debug=True)

Thank you for the reply !

I still get the following error-

" TypeError: Unexpected keyword argument ‘sort_action’ "

Please help. Thanks !

What version of Dash are you using? I am using the latest (see versions below) and I don’t get this error.

dash                      1.5.1    
dash-bootstrap-components 0.7.2    
dash-core-components      1.4.0    
dash-daq                  0.2.2    
dash-html-components      1.0.1    
dash-renderer             1.2.0    
dash-table                4.5.0  

sort_action is a valid keyword based on the docs

Thanks @flyingcujo - Upgrading the Dash fixed the issue.

Do you know how I can select multiple values per column for filtering ? Right now, i have these arguments

    columns=[{"name": i, "id": i, "selectable": True} for i in df.columns],
    data=df.to_dict('records'),
    editable=True,
    filter_action="native",
    sort_action="native",
    sort_mode="multi",
    column_selectable="multi",
    row_selectable=True,
    row_deletable=True,
    selected_columns=[],
    selected_rows=[],
    page_action="native",
    page_current= 0,
    page_size= 10,
    export_format='xlsx',
    export_headers='display',
    merge_duplicate_headers=True 

Thanks in advance for your help !

Unfortunately I don’t…I haven’t tried doing this as my app does not allow users to select values from the table.

No issues, thanks again !