【问题标题】:Return a Pandas DataFrame as a data_table from a callback with Plotly Dash for Python使用 Plotly Dash for Python 从回调中返回 Pandas DataFrame 作为 data_table
【发布时间】:2019-03-20 20:37:25
【问题描述】:

我想读取一个 .csv 文件并返回一个 groupby 函数作为回调,以显示为带有“dash_table”库的简单数据表。 @Lawliet 的有用答案显示了如何使用“dash_table_experiments”库来做到这一点。这是我卡住的地方:

import pandas as pd
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table
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([
    dash_table.DataTable(
        id = 'datatable',        
    ),

    html.Div([
        html.Button(id='submit-button',                
                children='Submit'
    )
    ]),    

])

@app.callback(Output('datatable','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()
        return dfgb.to_dict('rows')

if __name__ == '__main__':
    application.run(debug=False, port=8080)

【问题讨论】:

    标签: python pandas plotly-dash


    【解决方案1】:

    当您尝试将回调Output 组件注册为DataTable 时,应在回调中更新并返回DataTable 组件的所有必需/强制属性。在您的代码中,您只更新DataTable.data 而不是DataTable.column,一种简单的方法是返回预先填充了所有必需属性值的整个Datatable 组件。

    这是一个例子,

    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)
    
    

    看起来dash-table-experiments 已被弃用。

    编辑1:这是使用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)
    

    另一种方式:返回整个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)
    
    
    

    我提到了这个例子: https://github.com/plotly/dash-table/blob/master/tests/cypress/dash/v_copy_paste.py#L33

    【讨论】:

    • 谢谢@Lawliet。对不起,我的问题不是更清楚,我已经编辑了它,我正在尝试使用“dash_table”而不是“dash_table_experiments”返回 groupby 表。我想我可以使用 dash_table_experiments 代替,如您的示例所示。
    • 谢谢@Lawliet!您的解决方案适用于返回 dfgb,您只是忘记从示例中的回调中返回它,应该是:data = dfgb.to_dict('rows')
    • 一个快速(可选)跟进问题:)。你知道如何让数据表能够在用鼠标突出显示内容时复制到剪贴板,然后是 ctrl+C?
    • @sparrow Shift 和鼠标单击(或 Shift 和箭头)将让您突出显示,Ctlr+C 将复制到剪贴板。此功能默认存在。
    • @Lawliet,我也有类似的问题:stackoverflow.com/questions/60556896/…,如果你有空,请过来看看,谢谢。
    【解决方案2】:

    只需对update_datatable 稍作修改,您就几乎完成了它应该可以正常工作(未经测试):

    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()
            ])
    

    【讨论】:

    • 谢谢!这样可行。一个快速(可选)跟进问题:)。你知道如何让数据表能够在用鼠标突出显示内容时复制到剪贴板,然后是 ctrl+C?
    • @shivsn 我有一个类似的问题:stackoverflow.com/questions/60556896/…,如果你有空,请过来看看,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 2020-03-17
    • 2019-08-29
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多