matplotlib 在JupyterLab ipywidgets中,上下文管理器中的输出小部件显示pyplot图,无需显式调用

6za6bjd0  于 2023-03-03  发布在  其他
关注(0)|答案(1)|浏览(156)

如果我在两个JupyterLab单元格中运行此示例:
单元格[1]:

%matplotlib widget
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np

output = widgets.Output()
x = np.linspace(0, 2 * np.pi, 100)

with output:
    print('Print works as expected.')
    fig, ax = plt.subplots()
    
line, = ax.plot(x, np.sin(x))

单元格[2]:

int_slider = widgets.IntSlider(value=1, min=0, max=10, step=1)

def update(change):
    line.set_ydata(np.sin(change.new * x))
    # fig.canvas.draw() # This is not needed for update for some reason

int_slider.observe(update, 'value')
widgets.HBox([int_slider, output])

图形显示在单元格1下,带有文本的滑块显示在单元格2下。

预期行为将显示单元格2下的所有内容。

如果我使用“%matplotlib notebook”,则图形将从单元格1的输出中消失。滑块和文本将正确显示在单元格2下,同时显示“Javascript Error:未定义IPython”。

我还尝试了“%matplotlib inline”,它在单元格1下错误地显示了图形,图形不再跟随滑块。
**问题:**如何避免这种意外的结果,并使图形像print语句一样尊重Output小部件?

9wbgstp7

9wbgstp71#

溶液

在绘制数据后的第一个单元格中调用plt.close()。这会阻止图形立即显示。
在第二个单元格中创建一个新的Canvas图形,并使用它来存储原始图形。设置此Canvas并调用plt.show()来显示所需的绘图。它仍然是交互式的,但仅在运行第二个单元格后显示。

代码

############## First Cell ##############

%matplotlib widget
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np

output = widgets.Output()
x = np.linspace(0, 2 * np.pi, 100)

with output:
    print('Print works as expected.')
    fig, ax = plt.subplots()
    line, = ax.plot(x, np.sin(x))
    plt.close()
############## Second Cell ##############

int_slider = widgets.IntSlider(value=1, min=0, max=10, step=1)

fig2 = plt.figure()
manage = fig2.canvas.manager
manage.canvas.figure = fig
fig.set_canvas(manage.canvas)
plt.show()

def update(change):
    line.set_ydata(np.sin(change.new * x))

int_slider.observe(update, 'value')
widgets.HBox([int_slider, output])

相关问题