绘制上载CSV的问题

时间:2019-03-15 18:05:53

标签: plotly plotly-dash

我正在尝试使用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

1 个答案:

答案 0 :(得分:1)

您的代码有几个问题:

  1. 您给我们的错误源于在上传字段中使用multiple=True。这将导致回调函数接收列表,而不是contents, filename变量中的字符串。设置为False将解决该错误,并允许您按照我的预期仅选择一个文件进行上传。
  2. 您的CSV用制表符分隔,因此在您的delimiter='\t'通话中必须包含pd.read_csv
  3. 即使未选择任何文件,在页面加载时也会调​​用一次回调函数。在这种情况下,contents, filename都是None。我建议在尝试解析输入之前,在回调函数的开头进行检查。
  4. 您在日期列中使用了错误的名称。根据您在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