Return a Pandas DataFrame as a data_table from a callback with Plotly Dash for Python

前端 未结 2 932
半阙折子戏
半阙折子戏 2021-02-06 17:43

I would like to read a .csv file and return a groupby function as a callback to be displayed as a simple data table with \"dash_table\" library. @Lawliet\'s helpful answer shows

相关标签:
2条回答
  • 2021-02-06 18:34

    When you are trying to register the callback Output component as a DataTable, all the required / mandatory attributes for the DataTable component should be updated in the callback and returned. In your code, you are updating just DataTable.data and not DataTable.column, one easy way is to return the whole Datatable component which is prepopulated with all the required attribute values.

    Here is an example,

    import dash_html_components as html
    import dash_core_components as dcc
    import dash
    import dash_table
    import pandas as pd
    import dash_table_experiments as dt
    
    app = dash.Dash(__name__)
    
    #data to be loaded
    data = [['Alex',10],['Bob',12],['Clarke',13],['Alex',100]]
    df = pd.DataFrame(data,columns=['Name','Mark'])
    
    app.layout = html.Div([
        dt.DataTable(
                rows=df.to_dict('records'),
                columns=df.columns,
                row_selectable=True,
                filterable=True,
                sortable=True,
                selected_row_indices=list(df.index),  # all rows selected by default
                id='2'
         ),
        html.Button('Submit', id='button'),
        html.Div(id="div-1"),
    ])
    
    
    @app.callback(
        dash.dependencies.Output('div-1', 'children'),
        [dash.dependencies.Input('button', 'n_clicks')])
    def update_output(n_clicks):
    
        df_chart = df.groupby('Name').sum()
    
        return [
            dt.DataTable(
                rows=df_chart.to_dict('rows'),
                columns=df_chart.columns,
                row_selectable=True,
                filterable=True,
                sortable=True,
                selected_row_indices=list(df_chart.index),  # all rows selected by default
                id='3'
            )
        ]
    
    if __name__ == '__main__':
        app.run_server(debug=True)
    
    

    Looks like dash-table-experiments is deprecated.

    Edit 1: Here is one way of how it can be achieved using dash_tables

    import pandas as pd
    import dash
    import dash_core_components as dcc
    import dash_html_components as html
    import dash_table as dt
    from dash.dependencies import Input, Output, State
    
    df = pd.read_csv(
            'https://gist.githubusercontent.com/chriddyp/'
            'c78bf172206ce24f77d6363a2d754b59/raw/'
            'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'
            'usa-agricultural-exports-2011.csv')
    
    app = dash.Dash()
    application = app.server
    
    app.layout = html.Div([
        dt.DataTable(
            id = 'dt1', 
            columns =  [{"name": i, "id": i,} for i in (df.columns)],
    
        ),
        html.Div([
            html.Button(id='submit-button',                
                    children='Submit'
            )
        ]),    
    
    ])
    
    @app.callback(Output('dt1','data'),
                [Input('submit-button','n_clicks')],
                    [State('submit-button','n_clicks')])
    
    def update_datatable(n_clicks,csv_file):            
        if n_clicks:                            
            dfgb = df.groupby(['state']).sum()
            data_1 = df.to_dict('rows')
            return data_1
    
    if __name__ == '__main__':
        application.run(debug=False, port=8080)
    

    Another way: return the whole DataTable

    import pandas as pd
    import dash
    import dash_core_components as dcc
    import dash_html_components as html
    import dash_table as dt
    from dash.dependencies import Input, Output, State
    
    df = pd.read_csv(
            'https://gist.githubusercontent.com/chriddyp/'
            'c78bf172206ce24f77d6363a2d754b59/raw/'
            'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'
            'usa-agricultural-exports-2011.csv')
    
    app = dash.Dash()
    application = app.server
    
    app.layout = html.Div([
        html.Div(id="table1"),
    
        html.Div([
            html.Button(id='submit-button',                
                    children='Submit'
        )
        ]),    
    
    ])
    
    @app.callback(Output('table1','children'),
                [Input('submit-button','n_clicks')],
                    [State('submit-button','n_clicks')])
    
    def update_datatable(n_clicks,csv_file):            
        if n_clicks:                            
            dfgb = df.groupby(['state']).sum()
            data = df.to_dict('rows')
            columns =  [{"name": i, "id": i,} for i in (df.columns)]
            return dt.DataTable(data=data, columns=columns)
    
    
    if __name__ == '__main__':
        application.run(debug=False, port=8080)
    
    
    

    I referred to this example: https://github.com/plotly/dash-table/blob/master/tests/cypress/dash/v_copy_paste.py#L33

    0 讨论(0)
  • 2021-02-06 18:36

    You almost got it done just with minor modification in update_datatable it should work fine (not tested):

    def update_datatable(n_clicks,csv_file):            
        if n_clicks:                            
            dfgb = df.groupby(['state']).sum()
            return html.Div([dash_table.DataTable(
                    data=dfgb.to_dict('rows'),
                    columns=[{'name': i, 'id': i} for i in dfgb.columns],
                    style_header={'backgroundColor': "#FFD700",
                                  'fontWeight': 'bold',
                                  'textAlign': 'center',},
                    style_table={'overflowX': 'scroll'},  
                    style_cell={'minWidth': '180px', 'width': '180px',
                            'maxWidth': '180px','whiteSpace': 'normal'},                        
                             filtering=True,
                     row_selectable="multi",
                     n_fixed_rows=1),
                   html.Hr()
            ])
    
    0 讨论(0)
提交回复
热议问题