如何通过 Python 中的 Plotly 从 Dash 的下拉列表中选择数据集列?

Posted

技术标签:

【中文标题】如何通过 Python 中的 Plotly 从 Dash 的下拉列表中选择数据集列?【英文标题】:How to select dataset column from dropdown in Dash by Plotly in Python? 【发布时间】:2020-03-19 08:19:43 【问题描述】:

我希望获得一些关于在 Python 中使用 Dash by Plotly 创建仪表板的指导。虽然网上有很多文档和论坛帖子,但我觉得他们假设了一些我可能遗漏的知识,尤其是在正确使用回调实现交互性方面。

我想要实现的是一个仪表板,它可以让我:

    上传 Excel 文件 从 Excel 文件中选择一列 运行一个函数来处理该列中的数据 在表格中显示结果输出数据

我试图创建一个最小的工作示例,但一直在努力。以下是我迄今为止所管理的:

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

## 1. Define overall dashboard layout

Dashboard = dash.Dash(__name__, external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css'])
Dashboard.layout = html.Div([
                             html.H1('Dashboard Prototype', style='width':'100%', 'textAlign': 'center'),
                             dcc.Upload(
                                       id       = 'Dashboard_Input',
                                       children = html.A('Select Files'),
                                       style    = 'width': '100%', 'height': '60px', 'lineHeight': '60px', 'borderWidth': '1px',
                                                   'borderStyle': 'dashed', 'borderRadius': '5px', 'textAlign': 'center', 'display': 'inline-block',
                                       multiple = True
                                       ),
                             html.Br(),
                             html.Div(id='Dashboard_Dropdown'),
                             html.Br(),
                             html.Div(id='Dashboard_Output')
                           ])

## 2. Define functions to upload, process and present data

def selectData(contents, filename, date):

    content_type, content_string = contents.split(',')
    decoded = base64.b64decode(content_string)

    try:
        Raw_Data = pd.read_excel(io.BytesIO(decoded))
    except Exception as e:
        return html.Div(['There was an error processing this file.'])

    Dropdown = html.Div([                      
                         html.H4 (('File Name: ', filename), style='width':'100%', 'textAlign': 'center'),
                         html.Br(),
                         dcc.Dropdown(
                                      id          = 'Dataset_and_Column',
                                      options     = ['label': i, 'value': i for i in Raw_Data.columns],
                                      style       = 'width': '100%', 'height': '60px', 'lineHeight': '60px', 'borderWidth': '1px',
                                                     'borderStyle': 'dashed', 'borderRadius': '5px', 'textAlign': 'center', 'display': 'inline-block',
                                      placeholder =  'Select Dataset Column'
                                     ),
                         html.Br(),
                        ])

    return Dropdown

def processData(Raw_Data, Column_Label):

    # DO SOME PROCESSING THAT RESULTS IN 'TABLE':
    Table      = Table
    HTML_Table = html.Div([ 
                           dash_table.DataTable(
                                                data         = Table.to_dict('records'),
                                                columns      = ['name': i, 'id': i for i in Table.columns],
                                                style_cell   = 'textAlign': 'center', 'width': '100px', 
                                                editable     = False,
                                                style_header = 'fontWeight': 'bold', 'textAlign': 'center',
                                                style_table  = 'maxHeight': '50ex', 'width': '100%'
                                               ),
                           html.Hr()
                         ])
    return HTML_Table

## 4. Define callback functions

Dashboard.config.suppress_callback_exceptions = True

@Dashboard.callback(
                    Output('Dashboard_Dropdown', 'children'),
                    [Input('Dashboard_Input'   , 'contents')],
                    [State('Dashboard_Input'   , 'filename'), State('Dashboard_Input', 'last_modified')]
                   )
def createDropdown(list_of_contents, list_of_names, list_of_dates):
    if list_of_contents is not None:
       Dropdown = [selectData(c, n, d) for c, n, d in zip(list_of_contents, list_of_names, list_of_dates)]
       return Dropdown

################################################################################
################################################################################

# THIS BIT DOESN'T WORK #
# Need to make this callback function take an input of Raw_Date and Column_Label (selected from the dropdown) to run the processData() function.

@Dashboard.callback(
                    Output('Dashboard_Output'  , 'children'),
                    [Input('Dataset_and_Column', 'contents'), Input('Dataset_and_Column', 'value')],
                   )
def processSelectedColumn(contents, value):

    # HTML_Table = processData(contents, value)

    return value#HTML_Table

    # ^^^^^^ Note that this allow 'value' to be printed on the dashboard but 
    # when the commented 'HTML_Table' bits are uncommented it fails

################################################################################
################################################################################

## 6. Run dashboard

if __name__ == '__main__':
    Dashboard.run_server(debug=True)

这允许我选择一个 Excel 文件,然后打印从中创建的 Pandas 数据框的选定列,但我不确定如何将它们全部连接在一起以在选定列上运行我的 processData() 函数。

关于我没有正确使用或连接回调、函数等的任何想法?

【问题讨论】:

【参考方案1】:

您还需要processSelectedColumn 回调以从下拉列表中接受value 作为Input。将上传中的数据作为State 而不是Input 也可能/很好。这应该会为您提供执行所需计算所需的值。

【讨论】:

【参考方案2】:

答案:

下面是一些代码 sn-ps 从 Dash 的下拉列表中选择给定的列。

    数据集Housing price

    df= pd.read_csv(r"housing_price.csv")

    将列保存在变量options 中以调用破折号的 html 标记。

    options = [] for col in df.columns: options.append('label':''.format(col, col), 'value':col)

    为默认drop-down写一个html标签:

`

app.layout = html.Div([
        html.Label("Select a feature from drop-down to plot HISTOGRAM"),
        dcc.Dropdown(
            id = 'my_dropdown1',
            options= options,
            value='Choose columns'
        ),
        html.Label(id='my_label1'),

        html.Button(
            id='submit-button',
            n_clicks=0,
            children='Submit',
            style='fontSize':24, 'marginLeft':'30px'
        )
        ])

    编写回调:

    @app.callback( Output('my_label1', 'children'), [Input('my_dropdown1', 'value')] ) def update_dropdown(value): return 'You have chosen for histogram plot!'.format(value)

注意:如果您想使用State,请按照以下代码在用户单击提交按钮后激活对选定列的调用。

    激活基于State 的回调:

    @app.callback(
        Output('my_label1', 'children'),
        [Input('submit-button', 'n_clicks')],
        [State('my_dropdown1','value')]
        )
    
    def update_dropdown_state(n_clicks,value):
        return 'You have chosen  for histogram plot!'.format(value)
    

【讨论】:

以上是关于如何通过 Python 中的 Plotly 从 Dash 的下拉列表中选择数据集列?的主要内容,如果未能解决你的问题,请参考以下文章

Plotly:如何在绘图线图中的特定点添加标记(python / pandas)

如何使用 plotly 自定义平行类别图颜色? Python版

python - 如何使用plotly python中的下拉按钮更新多个散点图的数据?

如何使用 Python 中的 Plotly Express 为每个条形图添加可点击链接?

Plotly:悬停文本字段中的日期格式问题

通过单击 plotly 中的数据点打开 url?