ipywidget与matplotlib图总是显示两个轴

2ledvvac  于 2023-10-24  发布在  其他
关注(0)|答案(3)|浏览(111)

我试图创建一个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)

这是不希望的输出

小部件工作正常,只有上面的输出被更新,但我不明白为什么下面的输出也存在或如何删除它。我错过了什么明显的东西吗?

5vf7fwbs

5vf7fwbs1#

你可以使用widget的后端,%matplotlib widget,我想它就是为此而设计的。你需要把%matplotlib widget放在顶部(或者在matplotlib的东西被引入之前)。

更新:这里和下面也有matplotlib的一些指导,重点添加。

注意
要获得此处描述的交互式功能,您必须使用交互式后端。笔记本中的默认后端(内联后端)不是。backend_inline渲染图形一次,并在执行单元格时将静态图像插入笔记本中。由于图像是静态的,因此无法平移/缩放、接受用户输入或从其他单元格更新图像。
你的例子可以简化为:

%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)

m3eecexj

m3eecexj2#

jayveesa的答案是避免这种输出的一个很好的方法。我想为你的问题why添加一个答案。
小部件工作正常,只有上面的输出被更新,但我不明白为什么下面的输出也存在或如何删除它。我错过了什么明显的东西吗?
这里要做的一件有启发性的事情是注解掉update中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)

如果你这样做,你只会看到一个plot输出。这是因为当你使用jupyter notebook的%matplotlib inline后端时,在单元格中创建的任何图形都将在单元格完成运行时关闭并显示。(请参阅核心matplotlib开发人员的解释:https://github.com/matplotlib/matplotlib/issues/18248#issuecomment-675177108)。所以被黑色轮廓包围的图形来自display(ax.figure),下面的图形来自之前创建的图形。

nfg76nw0

nfg76nw03#

我有完全相同的问题,并使用**%matplotlib笔记本**不仅我有一个单一的数字,但我也可以互动(有x,y位置,旋转和改变3d图的Angular )

import ipywidgets as widgets
%matplotlib notebook
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.set_xlim(0, xij.max())
ax.set_ylim(0, yij.max())
ax.set_zlim(min_value, max_value)

def update_plot(frame=0):
    ax.clear()
    ax.set_xlim(0, xij.max())
    ax.set_ylim(0, yij.max())
    ax.set_zlim(min_value, max_value)
    surf = ax.plot_surface(xij, yij, data[frame], cmap=cm.coolwarm,
                   linewidth=0, antialiased=False)
 
widgets.interact(update_plot, frame=widgets.IntSlider(min=0, max=100, step=1, value=0))

相关问题