当前位置: 首页 > 知识库问答 >
问题:

Plotly Dash:如何提高对滑块更改的打印响应

任繁
2023-03-14

我正在开发一个工具来可视化一组参数对数学函数的影响,通过仪表板滑块修改这些参数。我使用了一些短跑教程示例中的方法,这些示例使用回调来替换图形。

这是可行的,但绘图对滑块更改的响应不如通过拖动旋转绘图等内置操作。当图形中有许多元素时,情况尤其如此。

是否有不同的方法可以提高响应能力?例如,是否有一种方法仅针对已更改的绘图元素,而不是替换整个图形?

这是一个最小的工作示例,由一个静态圆(有许多示例)和一个通过滑块旋转的线段组成。直线段的旋转非常不平稳。

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
from dash.dependencies import Input, Output, State
import numpy as np

app = dash.Dash(__name__)

# plot a circle
t = np.linspace(0, 2*np.pi, 10000)  # intentionally use many points to exaggerate the issue
x = np.cos(t)
y = np.sin(t)
z = np.zeros_like(t)
marker_size = 4
fig = go.Figure()
fig.add_trace(go.Scatter3d(x=x, y=y, z=z, mode='lines'))
fig.add_trace(go.Scatter3d(
    x=[0.0, 0.0], y=[0.0, 0.0], z=[0.0, 0.0],
    marker=go.scatter3d.Marker(size=marker_size),
    line=dict(width=3.0),
    showlegend=False,
))

fig.update_layout(
    uirevision='constant',
    autosize=False,
    width=900,
    height=900,
    scene=dict(
        xaxis=dict(range=[-1, 1]),
        yaxis=dict(range=[-1, 1]),
        zaxis=dict(range=[-1, 1.0]),
        aspectratio=dict(x=2, y=2, z=2),
    ),
)

app.layout = html.Div(children=[
    dcc.Graph(
        id='example-graph',
        figure=fig
    ),
    html.Div(
        [
            dcc.Slider(
                id='slider-phi',
                min=0.0,
                max=360.0,
                step=1.0,
                value=0.0,
                marks={0: '0', 180: '180', 360: '360'},
                updatemode='drag',
            ),
        ],
        style=dict(width='50%'),
    ),
    html.Div(children='', id='output-box'),
])

@app.callback(
    Output('example-graph', 'figure'),
    [Input('slider-phi', 'value')],
    [State('example-graph', 'figure')]
)
def display_structure(phi, myfig):
    myfig['data'][1]['x'][1] = np.cos(np.radians(phi))
    myfig['data'][1]['y'][1] = np.sin(np.radians(phi))
    myfig['data'][1]['z'][1] = 0

    return myfig

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

共有2个答案

骆嘉石
2023-03-14

看起来,虽然display\u structure在适当的位置修改了myfig,但返回值被视为一个全新的绘图,该绘图将重新绘制。

回调是否可能不需要返回值?如果您的函数修改了绘图属性,则可以将其设置到位。

仅供参考:我使用bokeh,对plotly了解有限。

邹星火
2023-03-14

缺乏反应可归因于两个关键因素。首先,正如您所注意到的,每次都会更新整个图形,而不仅仅是所需的跟踪。您可以通过将extendData属性作为目标而不是figure属性来避免这种情况,

@app.callback(Output('example-graph', 'extendData'), [Input('slider-phi', 'value')])
def update_data(phi):
    # tuple is (dict of new data, target trace index, number of points to keep)
    return dict(x=[[0, np.cos(np.radians(phi))]], y=[[0, np.sin(np.radians(phi))]]), [1], 2

第二个因素是回调是在服务器端而不是客户端执行的,即每次移动滑块时,请求都是客户端和服务器之间的交换。为了避免这种情况,可以通过将回调转换为客户端回调将更新移动到客户端,

app.clientside_callback(
    """
    function(phi) {
        // tuple is (dict of new data, target trace index, number of points to keep)
        return [{x: [[0, Math.cos(phi/180*Math.PI)]], y:[[0, Math.sin(phi/180*Math.PI)]]}, [1], 2]
    }
    """, Output('example-graph', 'extendData'), [Input('slider-phi', 'value')]
)

这将产生合理的响应。这是它在我的笔记本电脑上的样子,

为了完整起见,这里是完整的代码,

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
from dash.dependencies import Input, Output, State
import numpy as np

app = dash.Dash(__name__)

# plot a circle
t = np.linspace(0, 2*np.pi, 10000)  # intentionally use many points to exaggerate the issue
x = np.cos(t)
y = np.sin(t)
z = np.zeros_like(t)
marker_size = 4
fig = go.Figure()
fig.add_trace(go.Scatter3d(x=x, y=y, z=z, mode='lines'))
fig.add_trace(go.Scatter3d(
    x=[0.0, 0.0], y=[0.0, 0.0], z=[0.0, 0.0],
    marker=go.scatter3d.Marker(size=marker_size),
    line=dict(width=3.0),
    showlegend=False,
))

fig.update_layout(
    uirevision='constant',
    autosize=False,
    width=900,
    height=900,
    scene=dict(
        xaxis=dict(range=[-1, 1]),
        yaxis=dict(range=[-1, 1]),
        zaxis=dict(range=[-1, 1.0]),
        aspectratio=dict(x=2, y=2, z=2),
    ),
)

app.layout = html.Div(children=[
    dcc.Graph(
        id='example-graph',
        figure=fig
    ),
    html.Div(
        [
            dcc.Slider(
                id='slider-phi',
                min=0.0,
                max=360.0,
                step=1.0,
                value=0.0,
                marks={0: '0', 180: '180', 360: '360'},
                updatemode='drag',
            ),
        ],
        style=dict(width='50%'),
    ),
    html.Div(children='', id='output-box'),
])

app.clientside_callback(
    """
    function(phi) {
        // tuple is (dict of new data, target trace index, number of points to keep)
        return [{x: [[0, Math.cos(phi/180*Math.PI)]], y:[[0, Math.sin(phi/180*Math.PI)]]}, [1], 2]
    }
    """, Output('example-graph', 'extendData'), [Input('slider-phi', 'value')]
)

if __name__ == '__main__':
    app.run_server(debug=True)
 类似资料:
  • 我正在使用改型,我想访问从服务器返回的JSON响应。有人能给我提个建议吗?谢谢

  • APIService: 在活动调用API中:

  • 问题内容: 我一直在寻找有关如何执行此操作的答案,但似乎无法弄清楚(甚至在查看jQuery UI主题文档时也是如此)。当我从左向右移动滑块时,我希望滑块旋钮左侧的部分变为橙色(而不是默认的灰色)。 jQuery主题卷生成了以下CSS。大概.ui-widget- header背景色可以控制它,但是似乎没有。也不向其他任何类别添加背景色。知道如何解决此问题,以便在水平滑动时获得不同的颜色吗? JQUE

  • 我正在制作一个视频播放器,我想用一个滑块作为时间轴,我想将滑块从第一张图片更改为第二张图片 我可以用css代码来做这件事吗?如果是,此代码是什么

  • 问题内容: 关于这个主题我有一个问题,如果有人知道是否可以覆盖/变化较大的字体(字体类型,大小,颜色),用于MessageFormat中headerFormat缺憾与JTable.PrintMode或我必须画g2.drawString(“我的头/页脚”)和JTable#print()分别 问题答案: 正如每个人都已经提到的那样(当我在假期放松时:-)-TablePrintable紧密结合以确保机密

  • 问题内容: 我创建了一个UIAlertController 但是之后,我想更改UIAlertController的高度吗?我怎样才能做到这一点? 问题答案: 我发现您可以在显示视图控制器之前添加约束