如何在 Python 中通过 Plotly 从 Dash 中的下拉列表中 select 数据集列?
How to select dataset column from dropdown in Dash by Plotly in Python?
我希望在 Python 中获得一些关于使用 Plotly 的 Dash 创建仪表板的指导。虽然网上有很多文档和论坛帖子,但我觉得它们假定了我可能缺少的一些知识,尤其是正确使用回调实现交互性方面的知识。
我想要实现的是一个仪表板,它将允许我:
- 上传 Excel 文件
- Select Excel 文件中的一列
- 运行 处理该列数据的函数
- 在 table
中显示结果输出数据
我曾尝试创建一个最小的工作示例,但遇到了困难。这是我到目前为止所管理的内容:
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)
这允许我 select 一个 Excel 文件,然后打印从它创建的 Pandas 数据框的 selected 列,但我不确定具体如何将它们全部连接到 运行 我在 selected 列上的 processData()
函数。
关于我没有正确使用或连接回调、函数等的任何想法?
您需要 processSelectedColumn
回调来接受下拉列表中的 value
作为 Input
。将上传的数据作为 State
而不是 Input
也可能是 possible/good。这应该会为您提供执行所需计算所需的值。
答案:
下面是 select 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
,请按照以下代码在用户单击提交按钮后激活对 selected 列的调用。
激活基于 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 创建仪表板的指导。虽然网上有很多文档和论坛帖子,但我觉得它们假定了我可能缺少的一些知识,尤其是正确使用回调实现交互性方面的知识。
我想要实现的是一个仪表板,它将允许我:
- 上传 Excel 文件
- Select Excel 文件中的一列
- 运行 处理该列数据的函数
- 在 table 中显示结果输出数据
我曾尝试创建一个最小的工作示例,但遇到了困难。这是我到目前为止所管理的内容:
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)
这允许我 select 一个 Excel 文件,然后打印从它创建的 Pandas 数据框的 selected 列,但我不确定具体如何将它们全部连接到 运行 我在 selected 列上的 processData()
函数。
关于我没有正确使用或连接回调、函数等的任何想法?
您需要 processSelectedColumn
回调来接受下拉列表中的 value
作为 Input
。将上传的数据作为 State
而不是 Input
也可能是 possible/good。这应该会为您提供执行所需计算所需的值。
答案:
下面是 select 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
,请按照以下代码在用户单击提交按钮后激活对 selected 列的调用。
激活基于
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)