此组件的无效道具,无法更新破折号中的图形

invalid prop for this component, can't update a graph in dash

我是新手,目前正在通过 windows 进行破折号工作。我有以下脚本,我在其中尝试通过单击按钮来更新具有不同值的图形。该程序非常简单,但到目前为止还无法运行。 我在这里和 dash 社区进行了研究,但无济于事。

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# Some color in here
colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}

# this graph appears by default, but is never updated
trace_1 = go.Scatter(
            x = [5, 4, 3, 2, 1, 20, 2.5, 3],
            y = [1, 2, 3, 5, 7.3, -11, 7, 5]
        )

layout = go.Layout(title = 'Título de gráfica')
fig = go.Figure(data = [trace_1], layout = layout)

app.layout = html.Div(style = {'backgroundColor': colors['background']},
    children = [
    html.H3(
        children = 'Some title in here', 
            style = {
            'textAlign': 'center',
            'color': colors['text']
        }
    ),
    
# Button
    html.Button(
        children = 'Change', 
        id = 'button-1',
        n_clicks = 0,
        style = {
            'color': colors['text']
        }
    ),


html.Div(
    [
    html.Br(),
    html.Br(),
    html.Label(
        ['choose something'],
        style = {
            'font-weight': 'bold',
            'text-align': 'center',
            'color': colors['text']
        }
    ),
#These values are not working right now... just for fun right now
        dcc.Dropdown(
            id = 'dropo_1',
            options = [
                {'label' : '2048', 'value':'2048'},
                {'label' : '2560', 'value':'2560'},
                {'label' : '3200', 'value':'3200'}
            ],
            value = '2048',
            multi = False,
            disabled = False,
            persistence = 'string',
            persistence_type = 'session'
        ),
        html.Br(),
        dcc.Dropdown(
            id = 'dropo_2',
            options = [
                {'label' : '2048', 'value':'2048'},
                {'label' : '2560', 'value':'2560'},
                {'label' : '3200', 'value':'3200'}
            ],
            value = '2048',
            multi = False,
            disabled = False,
            persistence = 'string',
            persistence_type = 'session'
        )
        ],className = 'three columns'
    ),

    
# graph
    html.Div(
        [
        dcc.Graph(id = 'graf-1', figure = fig)
        ],className = 'eight columns'
    )
    ]
)

# Click and other values
@app.callback(
    Output('graf-1', 'fig'),
    [Input('button-1', 'n_clicks')]
)

def update_values(n_clicks):
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0]

    if 'button-1' in changed_id:

        trace_1 = go.Scatter(
            x = [5, 2, 5, 1, 7, 2, 3, 7],
            y = [3, 4, 3, 4, 3, 5, 7, 8]
        )
        layout = go.Layout(title = 'Nueva gráfica')
        fig = go.Figure(data = [trace_1], layout = layout)
        return (fig) 
    else:
        print('not working')
        

if __name__ == '__main__':
    app.run_server(port=3040, debug=True)

程序允许我将它上传到我的本地主机,但是按钮不起作用,图表不会更新,并且 dash 告诉我这个错误(不要注意不同的标题):

要更新 ddc.Graph 组件,您需要更新 figure 而不是 'fig'。

@app.callback(
    Output('graf-1', 'figure'),
    [Input('button-1', 'n_clicks')]
)

查克·塔克, 在某些脚本中我有 plotly.graph_objs,在其他一些脚本中我有 plotly.graph_objects,但这似乎不是问题所在。 我正在从各种来源阅读,尤其是

还有一个似乎很重要的PreventUpdate。我也忽略了 daq.BooleanSwitch 的 html.button(html.Button 的值为 None,似乎它增加了我的问题)...无论如何...经过如此多的尝试和重做,我发布了解决方案(以防更多新手遇到此类问题):

import dash
import dash_daq as daq
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
from dash.exceptions import PreventUpdate

# Esto llama un archivo .css para hacer la partición html.
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# Le damos color a esto
colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}
trace_1 = go.Scatter(
    x = [2,3,4,5,6,7,8,9,10,11,12,13,14,15],
    y = [4,6,8,10,12,14,16,18,20,22,24,26,28,30]
)

layout = go.Layout(title = 'Título de gráfica')
fig = go.Figure(data = [trace_1], layout = layout)


app.layout = html.Div(style = {'backgroundColor': colors['background']},
    children = [

# H3 es para marcar el título, es el mediano que los demás, H1 es súper grande.
    html.H3(
        children = 'Ejemplo fácil para chequear botones-gráficas-menus', 
            style = {
            'textAlign': 'center',
            'color': colors['text']
        }
    ),

# Div parece que divide éste párrafo abajo de lo anterior
    html.Div(
        id= 'respuesta',
        children= 'Clickea el botón',
          style = {
            'textAlign': 'center',
            'color': colors['text']
        }
    ),
# Se define el botón:
    daq.BooleanSwitch(
        id = 'Swtc_1',
        on = False
    ),
    
    html.Div(
        [
        html.Br(),
        html.Br(),
        html.Label(
            ['Elija algo'],
            style = {
                'font-weight': 'bold',
                'text-align': 'center',
                'color': colors['text']
            }
        ),
        dcc.Dropdown(
            id = 'dropo_1',
            options = [
                {'label' : '2048', 'value':'2048'},
                {'label' : '2560', 'value':'2560'},
                {'label' : '3200', 'value':'3200'}
            ],
            value = '2048',
            multi = False,
            disabled = False,
            persistence = 'string',
            persistence_type = 'session'
        ),
        html.Br(),
        dcc.Dropdown(
            id = 'dropo_2',
            options = [
                {'label' : '2048', 'value':'2048'},
                {'label' : '2560', 'value':'2560'},
                {'label' : '3200', 'value':'3200'}
            ],
            value = '2048',
            multi = False,
            disabled = False,
            persistence = 'string',
            persistence_type = 'session'
        )
        ],className = 'three columns'
    ),
        
# Ponemos la gráfica
    html.Div(
        [
        dcc.Graph(id = 'plot_id', figure = fig)
        ],className = 'eight columns'
    )
    ]
)

# Acá se genera la interacción.
@app.callback(
    Output('plot_id', 'figure'),
    [Input('Swtc_1', 'on')]
)

# Función 
def update_output(on):
    if on is True:
        trace_1 = go.Scatter(
            x = [4,6,8,10,12,14,16,18,20,22,24,26,28,30],
            y = [2,3,4,5,6,7,8,9,10,11,12,13,14,15]
        )
        layout = go.Layout(title = 'Título de gráfica')
        fig = go.Figure(data = [trace_1], layout = layout)
        return (fig)
    else:
        raise PreventUpdate
        
   

if __name__ == '__main__':
    app.run_server(port=3040, debug=True)

所以,现在正在运行,它正在用新值更新图表。

P.s.- 对于像我这样的新手,记得也要安装 dash_daq(pip install dash_daq)(我卡住了,它没有预装 dash)