英文:
Plotly in Jupyterlab: difference between show method and display (effect on plotly on_change)
问题
在JupyterLab中,使用Plotly,我已经设置了一个回调来在缩放时更新y轴。
请参考下面的代码以获取完整示例。
缩放功能通过on_change与布局连接。
当使用IPython的display或直接使用fig显示图形时,y轴会正确更新。但是,如果使用figure.show()方法,则停止工作。
在这种特殊情况下,这种方法存在什么问题?为什么on_change不再起作用?
我知道figure.show()使用渲染器框架,但我无法理解它在这种“on_change”情况下的功能。
有人能解释一下这个问题或者指导我查阅相关文档吗?
谢谢!
英文:
In JupyterLab, using Plotly, I have set up a callback to update the y-axis when zooming.
Please refer to the code below for a complete example.
The zoom function is connected to the layout using on_change.
The yaxis updates correctly when the figure is displayed using IPython's display or directly with fig. However, it stops working if the figure.show() method is used.
What is the issue with this method in this particular scenario? Why does on_change no longer work?
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
I am aware that figure.show() utilizes the renderers framework, but I am unable to understand its functionality in this "on_change" scenario.
Could someone shed some light on this or direct me to the appropriate documentation?
Thank you!
答案1
得分: 1
-
使用
show()方法会导致on_change处理程序不起作用的问题,是因为fig.show()实际上调用了plotly.io.show()方法,该方法根据指定的渲染器重新呈现对象本身。然而,on_change事件处理程序是一个独立的事件模块,不是图形的属性的一部分。因此,在 plotly.io 重新呈现时,它不会包括在内,fig.show()方法不会携带on_change()设置。另一方面,执行fig/display(fig)只是在 JupyterLab/Notebook 中显示对象,而不重新呈现,因此没有问题。 -
如果你使用
show()来传递配置参数,那可能是问题所在。fig.show(config=config)方法实际上设置了图形的私有属性_config,它继承自父类BaseFigure,唯一修改它的 API 接口是通过show()方法。因此,如果你想让on_change生效并同时设置配置,可以使用fig.__setattr__('_config', config)来设置图形的配置,例如scrollZoom = True。
顺便说一下,最好使用 fig.__getattributer__('_config') 先获取原始的 _config 值,然后与你要分配的新值合并。
# 设置回调
fig.layout.on_change(zoom, 'xaxis.range')
# 为示例准备鼠标滚轮缩放
_config = dict(scrollZoom=True)
# 获取原始 _config 属性并与你的合并
_config = fig.__getattribute__('_config') | _config
fig.__setattr__('_config', _config)
# 现在你同时拥有了 scrollZoom 配置和 on_change 缩放回调,不要使用 fig.show()
fig
这不是官方方式,但在 plotly 解决 show() 问题之前,这是一种可接受的做法。
英文:
I also ran into this problem where using the show() method prevented the on_change handler from working.
-
The use of
fig.show()actually calls theplotly.io.show()method, which re-renders the object itself based on the specified renderer. However, theon_changeevent handler is a standalone event module, and is not part of the Figure's property. Therefore, it will not be included when plotly.io re-renders it, and thefig.show()method won't carryon_change()settings. On the other hand, executingfig/display(fig)just displays the object in JupyterLab/Notebook, without re-rendering, so there is no issue. -
If you are using
show()to pass the config parameter, that is likely where the problem is. Thefig.show(config=config)method actually sets the figure's private attribute_config, which inherits from the parent classBaseFigure, and the only API interface to modify it is through theshow()method. Therefore, if you want to makeon_changework and set config at the same time, usefig.__setattr__('_config', config)to set fig's config, such asscrollZoom = True.
Btw, it's a good idea to use fig.__getattributer__('_config') to get the original _config value first, and then merge it with the new value you want to assign.
...
# set callback
fig.layout.on_change(zoom, 'xaxis.range')
# prepare mouse wheel zoom for example
_config = dict(scrollZoom=True)
# get original _config attribute and merge with yours
_config = fig.__getattribute__('_config') | _config
fig.__setattr__('_config', _config)
# now you have both scrollZoom config and on_change zoom
# callback work together, and don't use fig.show()
fig
It's not the official way, but it's an acceptable practice until plotly solves the show() issue.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论