Plotly-Dash:如何在回调之间显示图形的相同选定区域? [英] Plotly-Dash: How to show the same selected area of a figure between callbacks?

查看:52
本文介绍了Plotly-Dash:如何在回调之间显示图形的相同选定区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Consider a plotly figure where you can select polynomial features for a line fit using JupyterDash:

如果您选择一个区域,然后为多项式特征选择另一个数字,则该图是这样的:

If you select an area and then choose another number for polynomial features, the figure goes from this:

...然后再回到这个:

... and back to this again:

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

So, how can you set things up so that the figure displays the same area of the figure every time you select another number of features and trigger another callback?

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)

推荐答案

这出奇的简单,只是增加了 Plotly 和 Dash 的功能和灵活性.只需添加

This is surprisingly easy and just adds to the power and flexibility of Plotly and Dash. Just add

fig.update_layout(uirevision='constant')

到你的代码,你很高兴:

to your code and you're good to go:

为了获得更多控制,您可以直接设置轴属性.来自文档:

For even more control you can set axis properties directly. From the documentation:

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

For finer control you can set these sub-attributes directly. For example, if your app separately controls the data on the x and y axes you might set xaxis.uirevision=*time* and yaxis.uirevision=*cost*. Then if only the y data is changed, you can update yaxis.uirevision=*quantity* and the y axis range will reset but the x axis range will retain any user-driven zoom.

完整代码:

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)

这篇关于Plotly-Dash:如何在回调之间显示图形的相同选定区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆