【问题标题】:interactive plot with two parameters and interdependent data using ipywidget使用 ipywidget 具有两个参数和相互依赖的数据的交互式绘图
【发布时间】:2019-09-19 12:11:33
【问题描述】:

我想创建一个 jupyter-notebook 单元格,显示带有 matplotlib 的交互式绘图,以说明噪声信号的平滑。在下面的示例中,我使用了 scikit-image 中的高斯滤波器。我希望通过滑块调节噪音水平和平滑程度。为此,我使用了 ipywidgets

最初我尝试了以下

import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
import skimage
%matplotlib inline

def plot_noise_filter(signal,cnts,sigma):
    s = signal/np.sum(signal)*cnts  #normalize the signal to have cnts counts
    noise = np.random.poisson(s)    #randomly generate poissonian noise
    filtered = skimage.filters.gaussian(noise,sigma)   #filter noisy signal with gauss filter
    f,ax = plt.subplots()                              #plot
    ax.plot(noise/np.max(noise))
    ax.plot(filtered/np.max(filtered))

c_slide = widgets.IntSlider(min=100,max=10000,step=10,description='counts')
s_slide = widgets.IntSlider(min=1,max=100,description='smoothing')

sig = np.heaviside(np.linspace(-1,1,100),1)+1
widgets.interact(plot_noise_filter,signal=widgets.fixed(sig),cnts=c_slide,sigma=s_slide)

原则上,这给了我想要的图,但是现在每次我使用滑块s_slide 时,都会调用该函数并生成一个新的随机信号,即使计数没有改变。我希望图中的噪声信号仅在移动相应的滑块时才发生变化。

我能想到的唯一解决方法是预先计算噪声信号并将其存储在一个数组中,然后根据滑块选择该数组的元素,但这不是很优雅,并且可能会非常消耗内存。

我当前的安装是使用 conda 和 python 3.7.3

ipywidgets                7.5.1
matplotlib                3.1.1
jupyter                   1.0.0
jupyter_client            5.3.1
jupyter_console           6.0.0
jupyter_core              4.4.0
notebook                  6.0.1
numpy                     1.17.2

欢迎任何帮助。提前致谢!

【问题讨论】:

    标签: python matplotlib jupyter-notebook ipywidgets


    【解决方案1】:

    首先,感谢您提供的非常清晰且可运行的示例。

    如何使用lru_cache 将信号和噪声生成线提取到缓存函数中?然后这部分将始终为给定的signalcnts 输入返回相同的值,只留下平滑在您移动该滑块时进行更改。

    import ipywidgets as widgets
    import matplotlib.pyplot as plt
    import numpy as np
    import skimage
    %matplotlib inline
    from functools import lru_cache
    
    @lru_cache(32)
    def make_sig_noise(signal, cnts):
        s = signal/np.sum(signal)*cnts  #normalize the signal to have cnts counts
        noise = np.random.poisson(s)    #randomly generate poissonian noise
        return s, noise
    
    def plot_noise_filter(signal,cnts,sigma):
        s, noise = make_sig_noise(tuple(signal), cnts)
        filtered = skimage.filters.gaussian(noise,sigma)   #filter noisy signal with gauss filter
        f,ax = plt.subplots()                              #plot
        ax.plot(noise/np.max(noise))
        ax.plot(filtered/np.max(filtered))
    
    c_slide = widgets.IntSlider(min=100,max=10000,step=10,description='counts')
    s_slide = widgets.IntSlider(min=1,max=100,description='smoothing')
    
    sig = np.heaviside(np.linspace(-1,1,100),1)+1
    widgets.interact(plot_noise_filter,signal=widgets.fixed(sig),cnts=c_slide,sigma=s_slide)
    

    【讨论】:

      猜你喜欢
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 2023-01-03
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      相关资源
      最近更新 更多