我正在尝试使用plotly / Dash构建仪表板,该仪表板允许用户上传CSV文件,然后绘制结果。我从破折号documentation中的示例中借来了 并试图拼凑出一个绘制图形的示例,但是我收到了一条错误消息,该错误消息已附在下面。
我的代码已附加:
import base64
import datetime
import io
import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_table
import plotly.graph_objs as go
import pandas as pd
graph_name = 'Time series plot'
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
colors = {
"graphBackground": "#212529",
"background": "#000000",
"text": "#ffffff"
}
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = 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': '10px'
},
# Allow multiple files to be uploaded
multiple=True
),
html.Div(id='output-data-upload'),
dcc.Graph(id='new-hydrograph')
])
def parse_contents(contents, filename):
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.'
])
if df.shape[1] == 4:
df = df.iloc[2:]
df.columns = ['Datetime', 'Depth (in)', 'Velocity (feet/sec)', 'Flow (MGD)']
else:
df.columns = ['Datetime', 'Rain (in)']
return df
@app.callback(Output('output-data-upload', 'children'),
[Input('upload-data', 'contents')],
[State('upload-data', 'filename')])
def update_output(list_of_contents, list_of_names):
if list_of_contents is not None:
children = [
parse_contents(c, n) for c, n in
zip(list_of_contents, list_of_names)]
return children
@app.callback(Output('new-hydrograph', 'figure'),
[Input('upload-data', 'contents'),
Input('upload-data', 'filename')])
def plot_graph(contents, filename):
df = parse_contents(contents, filename)
trace1 = go.Scatter(
x = df.date,
y = df['Depth (in)'],
mode = 'lines',
)
return {
'data': [trace1],
'layout': go.Layout(
title = graph_name,
plot_bgcolor = colors["graphBackground"],
paper_bgcolor = colors["graphBackground"])
}
if __name__ == '__main__':
app.run_server(debug=True)
我收到的错误消息是:
Traceback (most recent call last):
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\_compat.py", line 33, in reraise
raise value
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\_compat.py", line 33, in reraise
raise value
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
sk\app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
h-0.39.0-py3.6.egg\dash\dash.py", line 1073, in dispatch
response.set_data(self.callback_map[output]['callbac
File "C:\Users\hvkumar\AppData\Local\Continuum\Anacond
h-0.39.0-py3.6.egg\dash\dash.py", line 969, in add_conte
output_value = func(*args, **kwargs)
File "C:\Users\hvkumar\Documents\Atlanta\pressure_data
- Copy\app_1.py", line 93, in plot_graph
df = parse_contents(contents, filename)
File "C:\Users\hvkumar\Documents\Atlanta\pressure_data
- Copy\app_1.py", line 50, in parse_contents
content_type, content_string = contents.split(',')
AttributeError: 'list' object has no attribute 'split'
这是一个示例CSV
PRC-01 "Average=15min" "QualityFlag=FALSE" "QualityValue=FALSE"
DateTime "MP1\DFINAL" "MP1\VFINAL" "MP1\QFINAL"
M/d/yyyy h:mm:ss tt "inches" "feet/sec" "MGD"
1/1/2015 0:00 14.9748 3.69 7.976
1/1/2015 0:15 15.0504 3.64 7.934
1/1/2015 0:30 14.7672 3.79 8.047
1/1/2015 0:45 14.9844 3.68 7.97
1/1/2015 1:00 14.8416 3.52 7.53
1/1/2015 1:15 14.7108 3.55 7.497
答案 0 :(得分:1)
您的代码有几个问题:
multiple=True
。这将导致回调函数接收列表,而不是contents, filename
变量中的字符串。设置为False
将解决该错误,并允许您按照我的预期仅选择一个文件进行上传。delimiter='\t'
通话中必须包含pd.read_csv
。contents, filename
都是None
。我建议在尝试解析输入之前,在回调函数的开头进行检查。df['Datetime']
中定义的列,您需要parse_contents
。第3点和第4点在下面的修订功能中得到处理。不要忘记照顾第1点和第2点。
@app.callback(Output('new-hydrograph', 'figure'),
[Input('upload-data', 'contents'),
Input('upload-data', 'filename')])
def plot_graph(contents, filename):
fig = {
'layout': go.Layout(
title=graph_name,
plot_bgcolor=colors["graphBackground"],
paper_bgcolor=colors["graphBackground"])
}
if contents:
df = parse_contents(contents, filename)
trace1 = go.Scatter(
x=df['Datetime'],
y=df['Depth (in)'],
mode='lines',
)
fig['data'] = [trace1]
return fig