【问题标题】:Change content of image interactively using slider widgets使用滑块小部件以交互方式更改图像内容
【发布时间】:2018-01-19 06:22:03
【问题描述】:

我正在尝试使用滑块以交互方式更改图像的内容(例如,应用具有不同内核大小的中值操作)。

虽然如果我只显示一个结果图像(参见注释行),这很有效,但在使用 subplot 函数时会遇到麻烦,因为图像不会得到更新。

我错过了什么?

%matplotlib inline
from ipywidgets import interact, widgets
import matplotlib.pyplot as plt
import warnings

from skimage.morphology import disk
from skimage.filters import rank
from skimage.color import rgb2gray
import skimage.data


def f(Median_Size):
    selem = disk(int(Median_Size))
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        img_median = rank.median(img_gray, selem=selem) 

    ax_neu.imshow(img_median, cmap="gray")
    fig.canvas.draw()
    #plt.imshow(img_median, cmap="gray") #This would work
    #plt.show()

image = skimage.data.camera() #plt.imread("Test.png")       
img_gray = rgb2gray(image)

fig = plt.figure(figsize=(6, 4))
ax_orig = fig.add_subplot(121) 
ax_neu = fig.add_subplot(122) 

ax_orig.imshow(img_gray, cmap="gray")
ax_neu.imshow(img_gray, cmap="gray")

interact(f, Median_Size=widgets.IntSlider(min=1,max=21,step=2,value=1)) 

【问题讨论】:

  • 我不明白你的问题。据我所知,您的代码运行良好(使用plt.imread() 而不是skimage.data.camera())。包括关于子图的部分。您能否提供有关您遇到的问题的更多信息?
  • 我可以使用 jupyter notebook 4.4.1 和 python 2.7 和 matplotlib 2.1 100% 地重现这个问题。 @DizietAsahi 你用的是什么版本?
  • 有趣。我正在使用 matplotlib:2.0.2,jupyter:4.3.0,python:3.6.1
  • 哦,我应该指出我使用的是%matplotlib notebook 而不是inline,如果这样会有所不同(我在使用inline 时没有得到任何形式的交互)
  • @DizietAsahi 是的,这很重要。使用%matplotlib notebook 确实是一种可能的解决方案。

标签: python matplotlib ipython jupyter-notebook


【解决方案1】:

使用%matplotlib notebook

您可以使用笔记本后端来代替内联后端。这将允许按预期调用figure.canvas.draw(),将代码作为脚本运行。将%matplotlib inline 行替换为

%matplotlib notebook

并重新启动内核。

使用display

您可以display 更改后的新图形。缺点是它会创建两次输出。然后,一种解决方法是将交互放入一个新单元格中并捕获第一个单元格的输出。

%%capture
%matplotlib inline
from ipywidgets import interact, widgets
from IPython.display import display
import matplotlib.pyplot as plt
import warnings

from skimage.morphology import disk
from skimage.filters import rank
from skimage.color import rgb2gray
import skimage.data


def f(Median_Size):
    selem = disk(int(Median_Size))
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        img_median = rank.median(img_gray, selem=selem) 

    ax_neu.imshow(img_median, cmap="gray")
    fig.canvas.draw()
    display(fig)

image = skimage.data.camera() #plt.imread("Test.png")       
img_gray = rgb2gray(image)

fig = plt.figure(figsize=(6, 4))
ax_orig = fig.add_subplot(121) 
ax_neu = fig.add_subplot(122) 

ax_orig.imshow(img_gray, cmap="gray")
ax_neu.imshow(img_gray, cmap="gray")

在一个新的单元格中

interact(f, Median_Size=widgets.IntSlider(min=1,max=21,step=2,value=1));

然后输出将如下所示:

【讨论】:

  • 运行此示例(和原始示例)我注意到的一件事是更新可能需要一些时间。在 f() 中为过滤后的子图添加标题会使事情更清楚:ax_neu.set_title("Median filter size: {}".format(Median_Size))
  • 我遇到了类似的问题,但我的绘图中有更多的元素(1 个图像、1 个颜色图、一个线图和 2 个文本框)全部由 FloatSlider 控制并使用 @987654334 进行排列@。显示选项最适合我。
  • 另外,我不得不恢复到 Jupyter Notebook,因为在 Jupyter Lab 中只有第一个选项有效,但是图像之间的更新时间使得交互性变得毫无意义,因为你不欣赏动态变化图片。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 2015-06-25
相关资源
最近更新 更多