Saya mencoba membuat dasbor menggunakan plotly/Dash yang memungkinkan pengguna mengunggah file CSV dan kemudian memplot hasilnya. Saya telah meminjam dari contoh di dasbor dokumentasi dan mencoba mengumpulkan contoh yang memplot grafik tetapi saya mendapatkan pesan kesalahan yang saya lampirkan di bawah.

Kode saya terlampir:

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)

Pesan kesalahan yang saya dapatkan adalah:

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'

Berikut ini contoh 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
Harsh Vedant 15 Maret 2019, 21:05

1 menjawab

Jawaban Terbaik

Kode Anda memiliki beberapa masalah:

  1. Kesalahan yang Anda berikan kepada kami berasal dari penggunaan multiple=True di bidang unggahan. Ini menyebabkan fungsi panggilan balik menerima daftar, bukan string dalam variabel contents, filename. Menyetel ke False akan mengatasi kesalahan itu, dan memungkinkan Anda memilih hanya satu file untuk diunggah, seperti yang saya asumsikan Anda inginkan.
  2. CSV Anda dibatasi tab, jadi harus menyertakan delimiter='\t' dalam panggilan pd.read_csv Anda.
  3. Fungsi panggilan balik dipanggil sekali pada pemuatan halaman bahkan ketika tidak ada file yang dipilih. Dalam hal ini contents, filename keduanya None. Saya sarankan memeriksa ini di awal fungsi panggilan balik, sebelum mencoba mengurai input.
  4. Anda menggunakan nama yang salah untuk kolom tanggal. Anda membutuhkan df['Datetime'], sesuai dengan kolom yang Anda tentukan di parse_contents.

Poin 3 dan 4 diperhatikan dalam fungsi yang direvisi di bawah ini. Jangan lupa perhatikan poin 1 dan 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
1
Shovalt 17 Maret 2019, 15:34