При изменении параметра ipywidgets исчезает график
Пишу небольшой скрипт, который позволит определять положение максимумов функции. Максимумы определяю с помощью scipy.signal.find_peaks. В функции есть параметр distance, который определяет минимальное количество точек между максимумами. Хочу при его изменении перестраивать положение максимумов и видеть их значение. Для этой цели использую ipywidgets.
Когда значение переменной находится в диапазоне, где значение максимумов не меняется, то график отображается нормально. Но если я выхожу за этот диапазон, то график пропадает.
В чем может быть проблема?
%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
x = np.linspace(1500, 1600, num=1000)
y = np.cos(4*np.pi*190*1000/x)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, y)
peaks, _ = find_peaks(y, distance=10)
line1, = ax.plot(x[peaks], y[peaks], "x")
def update(d = widgets.IntText(10)):
peaks_new, _ = find_peaks(y, distance=d)
line.set_ydata(y)
line1.set_ydata(y[peaks_new])
fig.canvas.draw_idle()
print(y[peaks_new])
print(peaks_new)
interact(update);

Ответы (1 шт):
Попробуйте убрать верхнюю строку, вот эту:
%matplotlib notebook
У меня в Google Colab без неё сразу нормально заработало. Но может понадобиться сбросить настройки среды исполнения, если вы этот код уже выполняли до этого.
Другое дело, что у вас график настолько ровный, что от изменения значения виджета ничего не меняется. А если добавить в график рандомности:
y = np.cos(4*np.pi*190*1000/x) + np.random.rand(1000)/10
То там сразу логика ломается, нужно код самого update переделывать, чтобы он нормально работал. Видимо, нужно с нуля каждый раз весь график перерисовывать, а не только часть.
А вообще удобнее использовать слайдер, а не поле ввода:
interact(update, d=widgets.IntSlider(min=1, max=30, step=1, value=10));