Python-Dash下拉列表显示具有交互式回调的多个项目

时间:2018-03-01 18:34:29

标签: python plotly plotly-dash

我正在使用Dash by Plotly和python来创建一个Web应用程序。 我一直在努力在下拉元素上正确显示多个值。从pandas数据帧开始,我提取第1列,然后选择与第1列中的值对应的另一列2中的值。多个值将显示在下拉列表中。附件是应用程序正在做的GIF。我希望下拉列表2上的值在不同的行上是独立的值,即不同的值,而不是连接在一起。

我认为问题是我如何返回

中的值
 def update_dropdown2(wdg):
 wdgarray=df[ df['wdg'] == wdg ]['id'],
 return [{'label':i,'value':i} for i in wdgarray]

这是一个显示问题的gif文件 second dropdown element display on each line

以下是代码:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import dash
    import dash_core_components as dcc
    import dash_html_components as html
    import plotly.graph_objs as go
    from dash.dependencies import Input, Output

#create a dataframe with random data

df = pd.DataFrame(
    {'wdg': [10,10,10,20,20,20,30,30,30,40],
     'id': np.arange(0,100,10),
     'b': np.random.rand(10)*100,
     'c': np.random.rand(10)*100,
     'd': np.random.rand(10)*100,
     'e': np.random.rand(10)*100,
     'f': np.random.rand(10)*100,
     'g': np.random.rand(10)*100,
     'h': np.random.rand(10)*100,
     'k': np.random.rand(10)*100},

    columns=['wdg','id','b','c','d','e','f','g','h','k'])


app = dash.Dash()

#html layout
app.layout = html.Div([
    html.H1(
        children='Perfomance database web app',
        style={
            'textAlign': 'center',
            'color': colors['text']}
    ),

    html.Div([
        dcc.Dropdown(
            id='dropdown1',
            options=[{'label': i, 'value': i} for i in df.wdg.unique()],
            value='10'
        ),
        dcc.Dropdown(
            id='dropdown2',
            #options=[{'label': i, 'value': i} for i in mtrid_indicators],
            #value='1'
        ),
    ],
    style={'width': '49%', 'display': 'inline-block'}
    ),

    html.Div(id='tablecontainer'),

    html.Div(
        dcc.Graph(
            id='graph',

            style={'width':'600','height':'500'}
        ),
        style={'display':'inline-block'}
    ),

    ],
style={'width': '100%', 'display': 'inline-block'}
)

#callback to update dropdown 2
@app.callback(
    Output(component_id='dropdown2',component_property='options'),
    [Input(component_id='dropdown1',component_property='value')]
)

#function to that will update values in dropdown 2
def update_dropdown2(wdg):
    wdgarray=df[ df['wdg'] == wdg ]['id'],
    return [{'label':i,'value':i} for i in wdgarray]

#callback to update graph with values of dropdown 1 selecting pandas row
@app.callback(
    Output('graph', 'figure'), 
    [Input('dropdown1', 'value')]
)

#graph plot and styling
def update_graph(row):
    dff = df.iloc[int(row/10)].values # update with your own logic
    return {
        'data': [
                    go.Scatter(
                        x=np.arange(0,80,10),
                        y=dff,
                        mode='lines+markers',
                        line = dict(width = 5,color = 'rgb(200, 0, 0)'),
                        name='Torque curve',
                        marker = dict(
                        size = 10,
                        color = 'rgba(200, 0, 0, .9)',
                        line = dict(width = 2,color='rgb(0, 0, 0)')
                        )
                    ),
                ],
        'layout': go.Layout(
                    title='Torque Speed curve',

                    xaxis=dict(
        #               type='line',
                        title='Speed - (RPM)',
                        showgrid=True,
                        #zeroline=True,
                        showline=True,
                        gridcolor='#bdbdbd',
                        mirror="ticks",
                        ticks="inside",
                        tickwidth=1,
                        linewidth=2,
                        range=[0,100]
                    ),
                    yaxis=dict(
                        title= 'Torque - (lb-ft)',
                        titlefont=dict( color='rgb(200, 0, 0)' ),
                        tickfont=dict( color='rgb(200, 0, 0)' ),
                        range=[0, 120],
                        showgrid=True,
                        #zeroline=True,
                        showline=True,
                        gridcolor='#bdbdbd',
                        mirror="ticks",
                        ticks="inside",
                        tickwidth=1,
                        linewidth=2
                    ),
                    margin={'l': 60, 'b': 40, 't': 30, 'r': 60},
                    #legend={'x': 0.5, 'y': 1},
                    hovermode='closest',
                    showlegend=False,
                )
        }

if __name__ == '__main__':
    app.run_server()

1 个答案:

答案 0 :(得分:1)

在惊人的阴谋社区中来自pdh的解决方案是删除将大熊猫系列变为元组的逗号。 Link to solution from Plotly community

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
from dash.dependencies import Input, Output

#create a dataframe with random data

df = pd.DataFrame(
{'wdg': [10,10,10,20,20,20,30,30,30,40],
 'id': np.arange(0,100,10),
 'b': np.random.rand(10)*100,
 'c': np.random.rand(10)*100,
 'd': np.random.rand(10)*100,
 'e': np.random.rand(10)*100,
 'f': np.random.rand(10)*100,
 'g': np.random.rand(10)*100,
 'h': np.random.rand(10)*100,
 'k': np.random.rand(10)*100},

columns=['wdg','id','b','c','d','e','f','g','h','k'])


app = dash.Dash()

#html layout
app.layout = html.Div([
html.H1(
    children='Perfomance database web app',
    style={
        'textAlign': 'center',
        'color': colors['text']}
),

html.Div([
    dcc.Dropdown(
        id='dropdown1',
        options=[{'label': i, 'value': i} for i in df.wdg.unique()],
        value='10'
    ),
    dcc.Dropdown(
        id='dropdown2',
        #options=[{'label': i, 'value': i} for i in mtrid_indicators],
        #value='1'
    ),
],
style={'width': '49%', 'display': 'inline-block'}
),

html.Div(id='tablecontainer'),

html.Div(
    dcc.Graph(
        id='graph',

        style={'width':'600','height':'500'}
    ),
    style={'display':'inline-block'}
),

],
style={'width': '100%', 'display': 'inline-block'}
)

#callback to update dropdown 2
@app.callback(
Output(component_id='dropdown2',component_property='options'),
[Input(component_id='dropdown1',component_property='value')]
)

#function to that will update values in dropdown 2
def update_dropdown2(wdg):
wdgarray=df[ df['wdg'] == wdg ]['id'] # removed problematic comma
return [{'label':i,'value':i} for i in wdgarray]

#callback to update graph with values of dropdown 1 selecting pandas row
@app.callback(
Output('graph', 'figure'), 
[Input('dropdown1', 'value')]
)

#graph plot and styling
def update_graph(row):
dff = df.iloc[int(row/10)].values # update with your own logic
return {
    'data': [
                go.Scatter(
                    x=np.arange(0,80,10),
                    y=dff,
                    mode='lines+markers',
                    line = dict(width = 5,color = 'rgb(200, 0, 0)'),
                    name='Torque curve',
                    marker = dict(
                    size = 10,
                    color = 'rgba(200, 0, 0, .9)',
                    line = dict(width = 2,color='rgb(0, 0, 0)')
                    )
                ),
            ],
    'layout': go.Layout(
                title='Torque Speed curve',

                xaxis=dict(
    #               type='line',
                    title='Speed - (RPM)',
                    showgrid=True,
                    #zeroline=True,
                    showline=True,
                    gridcolor='#bdbdbd',
                    mirror="ticks",
                    ticks="inside",
                    tickwidth=1,
                    linewidth=2,
                    range=[0,100]
                ),
                yaxis=dict(
                    title= 'Torque - (lb-ft)',
                    titlefont=dict( color='rgb(200, 0, 0)' ),
                    tickfont=dict( color='rgb(200, 0, 0)' ),
                    range=[0, 120],
                    showgrid=True,
                    #zeroline=True,
                    showline=True,
                    gridcolor='#bdbdbd',
                    mirror="ticks",
                    ticks="inside",
                    tickwidth=1,
                    linewidth=2
                ),
                margin={'l': 60, 'b': 40, 't': 30, 'r': 60},
                #legend={'x': 0.5, 'y': 1},
                hovermode='closest',
                showlegend=False,
            )
    }

if __name__ == '__main__':
app.run_server()