我们如何使用提供数据框的函数使用回调在Dash Table中动态创建数据列 [英] How can we create data columns in Dash Table dynamically using callback with a function providing the dataframe

查看:196
本文介绍了我们如何使用提供数据框的函数使用回调在Dash Table中动态创建数据列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Inputs在Web上创建破折号表.但是问题是,数据是通过回调和先验从数据库创建的, 我不知道这些列的名称,除非使用回调函数创建了pandas dataframe. 我已经检查过我获得了正确的数据.但是无法显示它.我使用了多个输出选项(使用Dash 0.41)

我的代码如下:(我没有提供在回调 someFunc 中生成熊猫数据框的函数的详细信息, 因为对于此Dash代码TroubleShooting而言,这并不重要.

 import dash_table as dt

 def someFunc(ID, pattern_desc, file_path):

       ## do something 
      return df # pandas dataframe

#

 external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

 app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

 server = app.server

 app = dash.Dash(__name__)

 app.config.suppress_callback_exceptions = True
 app.css.config.serve_locally = True
 app.scripts.config.serve_locally = True


 app.layout = html.Div(
      children = [
      html.Div(
      id = 'title',
      children = appTitle,
      className = 'titleDiv'  
   ),
 html.Div(
    children = [
        html.Div(
            children = "Enter ID:",
            className = 'textDiv'
        ),
        dcc.Input(
            id = 'ID',
            type = 'text',
            value = 'ABCER1',
            size = 8),

        html.Div(
            children = "Enter Test Pattern",
            className = 'textDiv'
        ),
        dcc.Input(
            id = 'pattern_desc',
            type = 'text',
            value = 'Sample',
            size = 20),

         html.Div(
            children = "Enter File OutPut Path:",
            className = 'textDiv'
        ),
        dcc.Input(
            id = 'file_path',
            type = 'text',
            value = '',
            size = 30),

        html.Button(
            id = 'submit',
            n_clicks = 0,
            children = 'Search'
        )
    ]
),

    html.Div(
        id = 'tableDiv',
        children = dash_table.DataTable(
        id = 'table',
        style_table={'overflowX': 'scroll'},
        style_as_list_view=True,
        style_header={'backgroundColor': 'white','fontWeight': 
            'bold'},
         ),
        className = 'tableDiv'
    )
  ]
)

  # callback to update the table
  @app.callback([Output('table', 'data'),Output('table', 'columns')]
          [Input('submit', 'n_clicks')],
          [State('ID', 'value'),  State('pattern_desc', 'value'), 
        State('file_path', 'value')])
   def update_table(n_clicks, ID, pattern_desc, file_path):

         df = someFunc(ID, pattern_desc, file_path)
    mycolumns = [{'name': i, 'id': i} for i in df.columns]
        return html.Div([
                dt.DataTable(
            id='table',
            columns=mycolumns,
            data=df.to_dict("rows")
         )
        ])

因此,在这种情况下,使用3个输入参数的函数 someFunc 返回一个pandas数据框,该数据框可以基于输入具有不同的列.因此,应用布局应显示 回调函数的输出根据输入动态给出的那些列. 我应该用表格和列填充网页,但是却出现错误.运行此命令时,我会将通过函数生成的数据获取到文件中,但是破折号无法 在网页上生成了表格.我收到以下错误:

dash.exceptions.InvalidCallbackReturnValue:回调..table.data ... table.columns ..是一个多输出. 预期输出类型为列表或元组,但得到Div([DataTable(columns = [{'name':'pattern_desc','id':'pattern_desc'},......

不确定如何实现.任何帮助将不胜感激.

解决方案

在Dash回调中,您应该向2个单独的输出返回2个单独的值: [Output('table', 'data'),Output('table', 'columns')]

您要返回:

return html.Div([
                dt.DataTable(
            id='table',
            columns=mycolumns,
            data=df.to_dict("rows")
         )
        ])

只有1个输出.

Dash希望在列表或类似这样的元组中有2个返回值:

return("output1" , outputVariable2)

return[ Html.Div("text") , "output Text 2"]

为了解决问题,要么在一个元组或列表中返回2个值,要么编辑您的输出要求,因此只需要一个值.

从外观上看,您试图返回一个包含数据表的Div,因此您可以进行以下更改:

    html.Div(
        id = 'tableDiv',
        className = 'tableDiv'
    )

...

  @app.callback([Output('tableDiv', 'children')]
          [Input('submit', 'n_clicks')],
          [State('ID', 'value'),  State('pattern_desc', 'value'), 
        State('file_path', 'value')])
   def update_table(n_clicks, ID, pattern_desc, file_path):

         df = someFunc(ID, pattern_desc, file_path)
    mycolumns = [{'name': i, 'id': i} for i in df.columns]
        return html.Div([
                dt.DataTable(
            id='table',
            columns=mycolumns,
            data=df.to_dict("rows")
         )
        ])

I am trying to create dash table on Web using Inputs. However the issue is that the data is created from database from the callback and a priori, I do not know the names of the columns unless the pandas dataframeis created using the callback function. I have checked that I getting correct data. However not able to display it. I have used multiple output options (using Dash 0.41)

My code looks as follows: ( I have not provided the details of the function which generates the pandas dataframe in the callback someFunc, as that was not important for the purpose of this Dash code TroubleShooting.

 import dash_table as dt

 def someFunc(ID, pattern_desc, file_path):

       ## do something 
      return df # pandas dataframe

#

 external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

 app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

 server = app.server

 app = dash.Dash(__name__)

 app.config.suppress_callback_exceptions = True
 app.css.config.serve_locally = True
 app.scripts.config.serve_locally = True


 app.layout = html.Div(
      children = [
      html.Div(
      id = 'title',
      children = appTitle,
      className = 'titleDiv'  
   ),
 html.Div(
    children = [
        html.Div(
            children = "Enter ID:",
            className = 'textDiv'
        ),
        dcc.Input(
            id = 'ID',
            type = 'text',
            value = 'ABCER1',
            size = 8),

        html.Div(
            children = "Enter Test Pattern",
            className = 'textDiv'
        ),
        dcc.Input(
            id = 'pattern_desc',
            type = 'text',
            value = 'Sample',
            size = 20),

         html.Div(
            children = "Enter File OutPut Path:",
            className = 'textDiv'
        ),
        dcc.Input(
            id = 'file_path',
            type = 'text',
            value = '',
            size = 30),

        html.Button(
            id = 'submit',
            n_clicks = 0,
            children = 'Search'
        )
    ]
),

    html.Div(
        id = 'tableDiv',
        children = dash_table.DataTable(
        id = 'table',
        style_table={'overflowX': 'scroll'},
        style_as_list_view=True,
        style_header={'backgroundColor': 'white','fontWeight': 
            'bold'},
         ),
        className = 'tableDiv'
    )
  ]
)

  # callback to update the table
  @app.callback([Output('table', 'data'),Output('table', 'columns')]
          [Input('submit', 'n_clicks')],
          [State('ID', 'value'),  State('pattern_desc', 'value'), 
        State('file_path', 'value')])
   def update_table(n_clicks, ID, pattern_desc, file_path):

         df = someFunc(ID, pattern_desc, file_path)
    mycolumns = [{'name': i, 'id': i} for i in df.columns]
        return html.Div([
                dt.DataTable(
            id='table',
            columns=mycolumns,
            data=df.to_dict("rows")
         )
        ])

So in this case the function someFunc which takes the 3 input arguments returns a pandas dataframe which can have different columns based on the inputs. Thus the app layout should display those columns as given by the output of the callback function dynamically based on the inputs. I should be getting the webpage populated with table and columns, But instead getting an error. When I run this, I am getting the data generated through the function to the file, but dash is not able to generated the table on webpage. I get the following error:

dash.exceptions.InvalidCallbackReturnValue: The callback ..table.data...table.columns.. is a multi-output. Expected the output type to be a list or tuple but got Div([DataTable(columns=[{'name': 'pattern_desc', 'id': 'pattern_desc'}, ......

Not Sure How I can achieve that. Any help will be appreciated.

解决方案

In your Dash callback you are supposed to be returning 2 separate values to the 2 separate outputs: [Output('table', 'data'),Output('table', 'columns')]

You are returning:

return html.Div([
                dt.DataTable(
            id='table',
            columns=mycolumns,
            data=df.to_dict("rows")
         )
        ])

which is only 1 output.

Dash expects 2 return values in either a list, or a tuple like so:

return("output1" , outputVariable2)

or

return[ Html.Div("text") , "output Text 2"]

in order to fix the problem, either return 2 values in a tuple or list, or edit your output requirements so only one value is necessary.

From the looks of it you are trying to return a Div with a Datatable in it, so you could just make the following changes:

    html.Div(
        id = 'tableDiv',
        className = 'tableDiv'
    )

...

  @app.callback([Output('tableDiv', 'children')]
          [Input('submit', 'n_clicks')],
          [State('ID', 'value'),  State('pattern_desc', 'value'), 
        State('file_path', 'value')])
   def update_table(n_clicks, ID, pattern_desc, file_path):

         df = someFunc(ID, pattern_desc, file_path)
    mycolumns = [{'name': i, 'id': i} for i in df.columns]
        return html.Div([
                dt.DataTable(
            id='table',
            columns=mycolumns,
            data=df.to_dict("rows")
         )
        ])

这篇关于我们如何使用提供数据框的函数使用回调在Dash Table中动态创建数据列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆