英文:
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_change
event 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_change
work 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论