使用plotly-dash我可以通过选择硬编码的csv的列来绘制图形。我尝试了不同的示例,现在我也可以从上载的文件中打印/打印csv。但是,我想上传一个csv,并在下拉菜单中,我希望能够选择一列并进行绘制。
通过此操作,我可以通过从下拉菜单中选择列来从硬编码的csv中绘制线条和箱形图。
df = pd.read_csv('df_anomaly.csv')
html.Div([
html.H3([
dcc.Dropdown(
id = 'Dropdown',
options=[{'label': k, 'value': k} for k in list(df.columns.values)[1:]],
value='a',
placeholder="Name"),
]),
], className = "filter"),
html.Div([
html.Div([
html.Div([
dcc.Graph(id='Lineplot'),
], style={'width': '75%','display': 'inline-block', 'marginLeft': '15', 'marginTop': '15'}),
html.Div([
dcc.Graph(id='Boxplot')
], style={'width': '23.8%', 'display': 'inline-block', 'marginRight': '15','marginTop': '15','float':'right'})], style={
'padding': '10px 15px'
}),
], style={'padding': '5px 0px','backgroundColor': colors['grey'], 'marginTop': '8', 'marginBottom': '8'})
])
# Updating Observed Data Plot
@app.callback(
dash.dependencies.Output('Lineplot', 'figure'),
[dash.dependencies.Input('Dropdown', 'value')])
def update_graph(selector):
df_selected = init_calc(selector)
return {
'data': [go.Scatter(
y = np.array(df_selected['selected']),
mode = 'lines',
line = dict(
color = colors['red']
)
)],
'layout': go.Layout(
height=400,
title=go.layout.Title(
text='Line Plot',
font=dict(
color = colors['black'],
)
),
xaxis=dict(
title='x',
linecolor = colors['black'],
color = colors['black'],
ticks='inside',
zeroline = False,
),
yaxis=dict(
title='y',
linecolor = colors['black'],
color = colors['black'],
ticks='inside',
zeroline = False,
),
hovermode='closest',
)
}
# Updating Boxplot
@app.callback(
dash.dependencies.Output('Boxplot', 'figure'),
[dash.dependencies.Input('Dropdown', 'value')])
def update_boxplot(selector):
df_selected = init_calc(selector)
return {
'data': [go.Box(
name='',
y=df_selected['selected'],
marker = dict(
color = colors['orange']
)
)],
'layout': go.Layout(
height=400,
title=go.layout.Title(
text='Boxplot',
font=dict(
color = colors['black'],
)
),
xaxis=dict(
linecolor = colors['black'],
color = colors['black'],
zeroline = False,
),
yaxis=dict(
title='Traffic',
linecolor = colors['black'],
color = colors['black'],
zeroline = False,
ticks='inside',
),
),
}
def init_calc(selector):
df_selected = pd.DataFrame(columns=['selected'])
df_selected['selected'] = df[str(selector)]
return df_selected
#------------------------------------------------------------------------------------
# Running the App
if __name__ == '__main__':
app.run_server(debug=False)
此外,如果我添加这段代码,我可以打印上载的csv:
html.Div([
dcc.Upload(
id='upload-data',
children=html.Div([
'Drag and Drop or ',
html.A('Select Files')
]),
style={
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '2px'
},
# Allow multiple files to be uploaded
multiple=True
),
html.Div(id='output-data-upload'),
]),
def parse_contents(contents, filename, date):
content_type, content_string = contents.split(',')
decoded = base64.b64decode(content_string)
try:
if 'csv' in filename:
# Assume that the user uploaded a CSV file
df = pd.read_csv(
io.StringIO(decoded.decode('utf-8')))
elif 'xls' in filename:
# Assume that the user uploaded an excel file
df = pd.read_excel(io.BytesIO(decoded))
except Exception as e:
print(e)
return html.Div([
'There was an error processing this file.'
])
return html.Div([
html.H5(filename),
# html.H6(datetime.fromtimestamp(date)),
dash_table.DataTable(
data=df[:5].to_dict('records'),
columns=[{'name': i, 'id': i} for i in df.columns]
),
html.Hr(), # horizontal line
# For debugging, display the raw contents provided by the web browser
# html.Div('Raw Content'),
# html.Pre(contents[0:200] + '...', style={
# 'whiteSpace': 'pre-wrap',
# 'wordBreak': 'break-all'
# })
])
@app.callback(Output('output-data-upload', 'children'),
[Input('upload-data', 'contents')],
[State('upload-data', 'filename'),
State('upload-data', 'last_modified')])
def update_output(list_of_contents, list_of_names, list_of_dates):
if list_of_contents is not None:
children = [
parse_contents(c, n, d) for c, n, d in
zip(list_of_contents, list_of_names, list_of_dates)]
return children
稍作调整,我也可以手动选择列并绘制上载的csv的列,但我希望能够像对硬编码的列那样选择上载的csv的列。我该怎么办?
预先感谢
答案 0 :(得分:1)
在函数parse_contents
中,除了返回用于显示内容的html片段之外,还返回df
。称它为df_uploaded
。
然后在下拉菜单的html内容中,将df替换为df_uploaded,如下所示:
html.Div([
html.H3([
dcc.Dropdown(
id = 'Dropdown',
options=[{'label': k, 'value': k} for k in list(df_uploaded.columns.values)[1:]],
value='a',
placeholder="Name"),
]),
], className = "filter"),
通常,我要做的是在一个单独的.py文件(例如data_and_graphs.py)中分离出所有图形生成函数。在这里,我通常会使用一些返回图形对象示例的函数:
def generate_line_graph(x,y):
l_grf = go.Fig()
#add_trace()
#add_layout()
return l_grf
然后在布局中,我只是import data_and_graphs.py as grf
在有图形引用的地方,我将其表示为
dcc.Graph(
id='graph1',
figure=grf.l_grf
)
在同一行上,我将通过调用options=[{'label': k, 'value': k} for k in list(grf.df_uploaded_cols)]
来引用下拉列表中的df列
您只需将相关列放在分配给df_uploaded_cols
希望这会提供一些指针,用于调整代码以获取上载的csv列。