带有 matplotlib 图的 ipywidget 总是显示两个轴
ipywidget with matplotlib figure always shows two axes
我正在尝试创建一个 ipywidget
界面,其中包含一个 matplotlib
图形,该图形会在更改滑块时更新。它原则上有效,但它总是创建一个额外的图形。
代码如下:
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import widgets
from IPython.display import display, clear_output
# make a grid
x = np.linspace(0, 5, 100)
X, Y = np.meshgrid(x, x)
# create the layout with slider
out = widgets.Output(layout=widgets.Layout(height='300px', width = '400px', border='solid'))
slider = widgets.IntSlider(value=1, min=1, max=5)
w = widgets.VBox(children=(out, slider))
# axes to plot into
ax = plt.axes()
display(w)
def update(value):
i = slider.value
Z = np.exp(-(X / i)**2 - (Y / i)**2)
ax.pcolormesh(x, x, Z, vmin=0, vmax=1, shading='auto')
with out:
clear_output(wait=True)
display(ax.figure)
slider.observe(update)
update(None)
这是不需要的输出
小部件有效,只有上部输出更新,但我不明白为什么下部输出也存在或如何摆脱它。我是否漏掉了一些明显的东西?
您可以使用小部件后端 %matplotlib widget
,我 认为 是为此设计的。您需要将 %matplotlib widget
放在顶部(或在 matplotlib
内容被引入之前)。
更新:还有一些指导形式 matplotlib here 及以下,重点补充。
Note
To get the interactive functionality described here, you must be using
an interactive backend. The default backend in notebooks, the inline
backend, is not. backend_inline renders the figure once and inserts a
static image into the notebook when the cell is executed. Because the
images are static, they can not be panned / zoomed, take user input,
or be updated from other cells.
您的示例可以简化为:
%matplotlib widget
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import widgets
from IPython.display import display, clear_output
x = np.linspace(0, 5, 100)
X, Y = np.meshgrid(x, x)
slider = widgets.IntSlider(value=1, min=1, max=5)
ax = plt.axes()
display(slider)
def update(value):
i = slider.value
Z = np.exp(-(X / i)**2 - (Y / i)**2)
ax.pcolormesh(x, x, Z, vmin=0, vmax=1, shading='auto')
slider.observe(update)
update(None)
jayveesa 的回答是避免这种输出的好方法。我想为您的问题 why
添加一个答案。
The widget works, and only the upper output is updated, but I do not understand why the lower output also exists or how to get rid of it. Am I missing something obvious?
这里要做的一件有启发性的事情是注释掉 display
数字
更新中的行
def update(value):
i = slider.value
Z = np.exp(-(X / i)**2 - (Y / i)**2)
ax.pcolormesh(x, x, Z, vmin=0, vmax=1, shading='auto')
# with out:
# clear_output(wait=True)
# display(ax.figure)
update(None)
如果你这样做,你将只会看到一个绘图输出。这是因为当您使用 jupyter 笔记本的 %matplotlib inline
后端时,在单元格中创建的任何图形都将在单元格完成 运行 时关闭并显示。 (请参阅此处核心 matplotlib 开发人员的解释:https://github.com/matplotlib/matplotlib/issues/18248#issuecomment-675177108)。因此,黑色轮廓包围的图形来自 display(ax.figure)
,下方的图形来自较早创建的图形。
我正在尝试创建一个 ipywidget
界面,其中包含一个 matplotlib
图形,该图形会在更改滑块时更新。它原则上有效,但它总是创建一个额外的图形。
代码如下:
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import widgets
from IPython.display import display, clear_output
# make a grid
x = np.linspace(0, 5, 100)
X, Y = np.meshgrid(x, x)
# create the layout with slider
out = widgets.Output(layout=widgets.Layout(height='300px', width = '400px', border='solid'))
slider = widgets.IntSlider(value=1, min=1, max=5)
w = widgets.VBox(children=(out, slider))
# axes to plot into
ax = plt.axes()
display(w)
def update(value):
i = slider.value
Z = np.exp(-(X / i)**2 - (Y / i)**2)
ax.pcolormesh(x, x, Z, vmin=0, vmax=1, shading='auto')
with out:
clear_output(wait=True)
display(ax.figure)
slider.observe(update)
update(None)
这是不需要的输出
小部件有效,只有上部输出更新,但我不明白为什么下部输出也存在或如何摆脱它。我是否漏掉了一些明显的东西?
您可以使用小部件后端 %matplotlib widget
,我 认为 是为此设计的。您需要将 %matplotlib widget
放在顶部(或在 matplotlib
内容被引入之前)。
更新:还有一些指导形式 matplotlib here 及以下,重点补充。
Note
To get the interactive functionality described here, you must be using an interactive backend. The default backend in notebooks, the inline backend, is not. backend_inline renders the figure once and inserts a static image into the notebook when the cell is executed. Because the images are static, they can not be panned / zoomed, take user input, or be updated from other cells.
您的示例可以简化为:
%matplotlib widget
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import widgets
from IPython.display import display, clear_output
x = np.linspace(0, 5, 100)
X, Y = np.meshgrid(x, x)
slider = widgets.IntSlider(value=1, min=1, max=5)
ax = plt.axes()
display(slider)
def update(value):
i = slider.value
Z = np.exp(-(X / i)**2 - (Y / i)**2)
ax.pcolormesh(x, x, Z, vmin=0, vmax=1, shading='auto')
slider.observe(update)
update(None)
jayveesa 的回答是避免这种输出的好方法。我想为您的问题 why
添加一个答案。
The widget works, and only the upper output is updated, but I do not understand why the lower output also exists or how to get rid of it. Am I missing something obvious?
这里要做的一件有启发性的事情是注释掉 display
数字
def update(value):
i = slider.value
Z = np.exp(-(X / i)**2 - (Y / i)**2)
ax.pcolormesh(x, x, Z, vmin=0, vmax=1, shading='auto')
# with out:
# clear_output(wait=True)
# display(ax.figure)
update(None)
如果你这样做,你将只会看到一个绘图输出。这是因为当您使用 jupyter 笔记本的 %matplotlib inline
后端时,在单元格中创建的任何图形都将在单元格完成 运行 时关闭并显示。 (请参阅此处核心 matplotlib 开发人员的解释:https://github.com/matplotlib/matplotlib/issues/18248#issuecomment-675177108)。因此,黑色轮廓包围的图形来自 display(ax.figure)
,下方的图形来自较早创建的图形。