我想创建一个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
欢迎任何帮助。预先感谢!
答案 0 :(得分:0)
首先,感谢您提供了非常清晰且可运行的示例。
如何使用lru_cache
将信号和噪声生成线提取到缓存的函数中?然后,对于给定的signal
和cnts
输入,这部分将始终返回相同的值,仅留下平滑度即可随着移动该滑块而改变。
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)