【问题标题】:Plotly-Dash: How to show the same selected area of a figure between callbacks?Plotly-Dash:如何在回调之间显示图形的相同选定区域?
【发布时间】:2020-09-13 22:33:23
【问题描述】:

考虑一个绘图图,您可以在其中选择多项式特征以使用 JupyterDash 进行线拟合:

如果选择一个区域,然后为多项式特征选择另一个数字,则该图来自:

...然后又回到这个:

那么,如何进行设置,以便每次选择其他数量的特征并触发另一个回调时,图形显示图形的相同区域?

完整代码:

import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

from sklearn.preprocessing import PolynomialFeatures 
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import make_pipeline

from IPython.core.debugger import set_trace

# Load Data
df = px.data.tips()
# Build App
app = JupyterDash(__name__)
app.layout = html.Div([
    html.H1("ScikitLearn: Polynomial features"),
    dcc.Graph(id='graph'),
    html.Label([
        "Set number of features",
        dcc.Slider(id='PolyFeat',
    min=1,
    max=6,
    marks={i: '{}'.format(i) for i in range(10)},
    value=1,
) 
    ]),
])

# Define callback to update graph
@app.callback(
    Output('graph', 'figure'),
    [Input("PolyFeat", "value")]
)

def update_figure(nFeatures):
    
    global model

    # data
    df = px.data.tips()
    x=df['total_bill']
    y=df['tip']

    # model
    model = make_pipeline(PolynomialFeatures(nFeatures), LinearRegression())
    model.fit(np.array(x).reshape(-1, 1), y)
    x_reg = x.values
    y_reg = model.predict(x_reg.reshape(-1, 1))
    df['model']=y_reg

    # figure setup and trace for observations
    fig = go.Figure()
    fig.add_traces(go.Scatter(x=df['total_bill'], y=df['tip'], mode='markers', name = 'observations'))

    # trace for polynomial model
    df=df.sort_values(by=['model'])
    fig.add_traces(go.Scatter(x=df['total_bill'], y=df['model'], mode='lines', name = 'model'))
    
    # figure layout adjustments
    fig.update_layout(yaxis=dict(range=[0,12]))
    fig.update_layout(xaxis=dict(range=[0,60]))
    #print(df['model'].tail())
    fig.update_layout(template = 'plotly_dark')
    
    return(fig)

# Run app and display result inline in the notebook
app.enable_dev_tools(dev_tools_hot_reload =True)
app.run_server(mode='inline', port = 8040, dev_tools_ui=True, #debug=True,
              dev_tools_hot_reload =True, threaded=True)

【问题讨论】:

  • 这能回答你的问题吗? Freeze plotly-dash graph visualization
  • @emher 关闭,但不完全。我发现标题与freeze 部分有点误导。这听起来好像这个数字对所有变化都没有反应。除此之外,您的建议是fig.update_layout(uirevision='some-constant'),这可能会让读者相信它是一些 numerical 常量的占位符。事实证明,任何字符串都可以工作,所以fig.update_layout(uirevision='some-constant') 不是错误。即使fig.update_layout(uirevision='wrong') 也会触发相同的功能。
  • @emher 但是我写这个问题的主要原因是搜索[plotly] uirevision时它没有弹出。但我现在看到您的链接帖子缺少[plotly] 标签。我现在已经解决了。
  • @emher 根据我的第一条评论,您在回答 Whenever you need to reset the view, change the value to something else. 中的最后陈述并不完全正确。
  • 啊,是的,我知道我的措辞可能会被误解。我已经编辑了答案以使其更清楚。但是,我不确定我是否理解为什么“每当您需要重置视图时,将值更改为其他值。”不正确?

标签: python plotly plotly-dash jupyterdash


【解决方案1】:

这非常简单,并且增加了 Plotly 和 Dash 的功能和灵活性。 只需添加

fig.update_layout(uirevision='constant')

你的代码,你很高兴:

要获得更多控制,您可以直接设置轴属性。来自docs

为了更精细的控制,您可以直接设置这些子属性。为了 例如,如果您的应用分别控制 x 轴和 y 轴上的数据 你可以设置xaxis.uirevision=*time*yaxis.uirevision=*cost*。 那么如果只改变y数据,就可以更新 yaxis.uirevision=*quantity* 和 y 轴范围将重置,但 x 轴范围将保留任何用户驱动的缩放。

完整代码:

import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

from sklearn.preprocessing import PolynomialFeatures 
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import make_pipeline

from IPython.core.debugger import set_trace

# Load Data
df = px.data.tips()
# Build App
app = JupyterDash(__name__)
app.layout = html.Div([
    html.H1("ScikitLearn: Polynomial features"),
    dcc.Graph(id='graph'),
    html.Label([
        "Set number of features",
        dcc.Slider(id='PolyFeat',
    min=1,
    max=6,
    marks={i: '{}'.format(i) for i in range(10)},
    value=1,
) 
    ]),
])

# Define callback to update graph
@app.callback(
    Output('graph', 'figure'),
    [Input("PolyFeat", "value")]
)

def update_figure(nFeatures):
    
    global model

    # data
    df = px.data.tips()
    x=df['total_bill']
    y=df['tip']

    # model
    model = make_pipeline(PolynomialFeatures(nFeatures), LinearRegression())
    model.fit(np.array(x).reshape(-1, 1), y)
    x_reg = x.values
    y_reg = model.predict(x_reg.reshape(-1, 1))
    df['model']=y_reg

    # figure setup and trace for observations
    fig = go.Figure()
    fig.add_traces(go.Scatter(x=df['total_bill'], y=df['tip'], mode='markers', name = 'observations'))

    # trace for polynomial model
    df=df.sort_values(by=['model'])
    fig.add_traces(go.Scatter(x=df['total_bill'], y=df['model'], mode='lines', name = 'model'))
    
    # figure layout adjustments
    fig.update_layout(yaxis=dict(range=[0,12]))
    fig.update_layout(xaxis=dict(range=[0,60]))
    #print(df['model'].tail())
    fig.update_layout(template = 'plotly_dark')
    fig.update_layout(uirevision='constant')
    return(fig)

# Run app and display result inline in the notebook
app.enable_dev_tools(dev_tools_hot_reload =True)
app.run_server(mode='inline', port = 8040, dev_tools_ui=True, #debug=True,
              dev_tools_hot_reload =True, threaded=True)

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 2021-11-14
    • 2021-07-04
    • 2019-06-25
    • 2022-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    相关资源
    最近更新 更多