在 JupyterLab 中,使用 Plotly,我设置了一个回调来在缩放时更新 y 轴。
完整示例请参考下面的代码。
缩放功能使用 on_change 连接到布局。
当使用 IPython 的
yaxis
或直接使用 display
显示图形时,fig
会正确更新。但是,如果使用 figure.show()
方法,它就会停止工作。
在这种特定场景下,这种方法有什么问题?为什么 on_change 不再起作用?
import plotly.graph_objs as go
import pandas as pd
import numpy as np
x = np.linspace(0, 100, 1000)
y = 0.1* x * np.sin(2 * np.pi * 0.1 * x)
# Create the DataFrame
df = pd.DataFrame({'Time': x, 'Value': y})
df = df.set_index('Time')
fig = go.FigureWidget()
fig.add_trace(
go.Scatter(x=df.index, y=df['Value'], mode='lines')
)
fig.update_layout(
xaxis={'rangeslider_visible': True}
)
# callback function to update yaxis min and max upon zoom
def zoom(layout, xrange):
in_view = df.loc[fig.layout.xaxis.range[0]:fig.layout.xaxis.range[1]]
fig.layout.yaxis.range = [in_view.Value.min(), in_view.Value.max()]
fig.layout.on_change(zoom, 'xaxis.range')
#fig # on_change (zoom) works!
display(fig) # on_change (zoom) works!
#fig.show() # on_change (zoom) doesn't work
我知道
figure.show()
利用了渲染器框架,但我无法理解它在这个“on_change”场景中的功能。
有人可以阐明这一点或指导我找到适当的文档吗?
谢谢!
我也遇到了这个问题,使用 show() 方法会使 on_change 不起作用。我花了大半天终于弄清楚问题并得到解决方案。
1、fig.show()的使用实际上是调用plotly.io.show()方法,因此它是根据指定的渲染器重新渲染对象本身,然而,on_change监听器是一个独立的事件模块,并且不会出现在Figure的属性中,因此当plotly.io重新渲染它时,它不会包含on_change设置。这就是为什么 show() 方法不会携带 on_change() 设置。而执行fig/display(fig)只是显示jupyterlab/notebook中的对象,不涉及重新渲染,所以没有问题。
2,如果您使用 show() 来传递配置参数,这可能就是问题所在。 Fig.show(config=config)实际上是设置figure的私有属性'_config',该属性继承自父类BaseFigure,修改它的唯一api接口是通过show()方法。所以,如果你想让 on_change 工作并在同一个Fig上设置配置,只需使用Fig.__setattr__('_config', config)。达达!
顺便说一句,最好先使用Fig.__getattributer__('_config')获取原始的_config值,然后添加你想要分配的新值,例如scrollZoom=True。