首页 > 解决方案 > plotly dash:如何获取 csv 的标题作为下拉选项

问题描述

我正在写一个破折号应用程序。目前我的应用看起来像这样

`

import base64
import io
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import matplotlib.pyplot
from dash.dependencies import Input, Output
import dash_table_experiments as dt
import numpy as np

app = dash.Dash()
app.scripts.config.serve_locally = True

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
    ),



#plot dropdowns graph and tabel     
    html.Div(id='output-data-upload'),  

    html.Div(dt.DataTable(rows=[{}]), style={'display': 'none'}),

            ],

          )
#%%methodes 
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')),sep=';',header=6)
        elif 'xls' in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded),sep=';',header=6)
    except Exception as e:
        print(e)
        return html.Div([
            'There was an error processing this file.'
        ])
    available_indicators=list(df)
    ind =np.delete(available_indicators,0),
    print (ind)
    return html.Div([
            #x-Achse
        html.Div('Choose Data for x-axis'),
        dcc.RadioItems(
                id='x_Achse',
                    options=[
                        {'label': i, 'value': i} for i in ind[0]],
        ),
            #y-Achse
        html.Label('Choose Data for y-axis'),
        dcc.Dropdown(
            id='y-Achse',
                options=[
                        {'label': i, 'value': i}for i in ind[0]],
                multi= True
        ),
        #Graph
        return_graph(df,1,1),
        html.H5(filename),
        # Use the DataTable prototype component:
        # github.com/plotly/dash-table-experiments
        dt.DataTable(rows=df.to_dict('records')),
        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'
        })
    ])

#%%
def return_graph(df, x_Werte, Y_Werte_Array):
 return dcc.Graph(id='Liniendiagramm',
               figure={
               'data': [go.Scatter(
                            x=df['Date/Time'],   #change to x_Werte
                            y=df['Var_01'],      #change to Y_Werte_Array[0]
                            text=df['Var_01'],   #change to Y_Werte_Array[0]
                            name='Var_01'        #change to Y_Werte_Array[0]
                            ),

                        go.Scatter(
                            x=df['Date/Time'],   #change to x_Werte
                            y=df['Var_02'],      #change to Y_Werte_Array[1]
                            text=df['Var_02'],   #change to Y_Werte_Array[1]
                            name='Var_02'        #change to Y_Werte_Array[1]
                            ),    
                        ]   
                    }
               )
#%%

#end Methoden            
#%%callback
@app.callback(Output('output-data-upload', 'children'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename'),
               Input('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

#%%      
  if __name__ == '__main__':
        app.run_server(debug=True)`

现在我的问题。我的应用程序中的下拉列表在方法 parse_contents 中。所以我得到一个错误,如果我尝试使用回调来获取下拉列表的值。下拉列表的选项是在此方法中计算的。我需要一个解决方案来获取 .csv 文件中的 Tabel 标题。使用标题的值作为下拉菜单的选项,并在方法 return_graph 中写入下拉菜单的选定值。

最后它必须看起来,所以 在这里输入图像描述, 但目前两个下拉菜单都是无用的,并且图表是由静态值绘制的,对不起代码中的德语单词和糟糕的英语。

标签: csvcallbackplotlydropdownplotly-dash

解决方案


所以现在我有一个解决我的问题的方法。如果有人想使用它,这里是代码。请注意,在“解析内容”方法中,参数 sep=';' 和 header=6 行,设置为静态参数。

`import base64
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import dash_table_experiments as dte
from dash.dependencies import Input, Output
import dash
import pandas as pd
import io



app = dash.Dash()

app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True

app.layout = html.Div([

    html.H5("Upload Files"),
    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'
        },

    ),


    html.Br(),
    html.Div("X_Achse"),
    dcc.Dropdown(id='x_Achse',
        multi = False,
        placeholder='Filter Column'),
    html.Div('Y_Werte'),
    dcc.Dropdown(id='y_Achse',
        multi = True,
        placeholder='Filter Column'),

    html.Div(id='graph'),
    html.Br(),
    html.H5("Updated Table"),
    html.Div(dte.DataTable(rows=[{}], id='table'))
    ])
# Functions
#%%
# file upload function
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')),sep=';',header=6)
        elif 'xls' in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded),sep=';',header=6)

    except Exception as e:
        print(e)
        return None
    return df
#%%
def return_graph(df, x_Werte, Y_Werte_Array):
    return dcc.Graph(id='Liniendiagramm',
               figure={
               'data': [                   #definiert die Daten welche visualisiert werden sollen
                       go.Scatter(
                            x=df[x_Werte],
                            y=df[Y_Werte_Array[i]],
                            text=df[Y_Werte_Array[i]],
                            name=Y_Werte_Array[i]                           
                            )
                       for i in range(0,len(Y_Werte_Array))
                        ]   
                    }
               )
#%%
@app.callback(Output('graph','children'),
              [Input('x_Achse','value'),
               Input('y_Achse','value'),
               Input('table','rows')])
def update_graph(x,y,c): 
    if x and y and c is not None:
        print (x)
        print (y)
#        print (c)
        dff = pd.DataFrame.from_dict(c)
#        print('anfang')
#        print(dff)
#        print ('ende')
        graph1=return_graph(dff,x,y)
#       print (c)    
        return graph1 #return_graph(c,a,b)
#%%
# callback table creation
@app.callback(Output('table', 'rows'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename')])
def update_output(contents, filename):
    if contents is not None:
        df = parse_contents(contents, filename)
        if df is not None:
           # print (df)
            return df.to_dict('records')
        else:
            return [{}]
    else:
        return [{}]
#%%
#callback update options of filter dropdown
@app.callback(Output('x_Achse', 'options'),
              [Input('table', 'rows')])
def update_x_Achse( tablerows):
    if tablerows is not None: 
        dff = pd.DataFrame(tablerows) # <- problem! dff stays empty even though table was uploaded

        print ("updating... dff empty?:"), dff.empty #result is True, labels stay empty

        return [{'label': i, 'value': i} for i in sorted(list(dff))]
#%%
@app.callback(Output('y_Achse', 'options'),
              [Input('table', 'rows')])
def update_y_Achse( tablerows):
    if tablerows is not None: 
        dff = pd.DataFrame(tablerows) # <- problem! dff stays empty even though table was uploaded

        print ("updating... dff empty?:"), dff.empty #result is True, labels stay empty

        return [{'label': i, 'value': i} for i in sorted(list(dff))]
#%%

app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

if __name__ == '__main__':
    app.run_server(debug=True)`

推荐阅读