python-3.x - 在茎图中使用交互小部件
问题描述
我正在尝试stem
在 Jupyter 笔记本中制作 Python 图。
剧情是这样的:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
f = 10
f_s = 100
t = np.linspace(0, 2, 2 * f_s, endpoint=False)
x = np.sin(f * 2 * np.pi * t)
X = fftpack.fft(x)
freqs = fftpack.fftfreq(len(x)) * f_s
fig, ax = plt.subplots()
ax.stem(freqs, np.abs(X))
ax.set_xlabel('Frecuency [Hz]')
ax.set_ylabel('Spectrum')
ax.set_xlim(-f_s / 2, f_s / 2)
ax.set_ylim(-5, 110);
我想在这篇文章Jupyter Notebook: interactive plot with widgets 中添加一个滑块。这篇文章中的解决方案
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
from ipywidgets import *
f = 10
f_s = 100
t = np.linspace(0, 2, 2 * f_s, endpoint=False)
x = np.sin(f * 2 * np.pi * t)
X = fftpack.fft(x)
freqs = fftpack.fftfreq(len(x)) * f_s
fig, ax = plt.subplots()
line, = ax.stem(freqs, np.abs(X))
ax.set_xlabel('Frecuency [Hz]')
ax.set_ylabel('Spectrum')
ax.set_xlim(-f_s / 2, f_s / 2)
ax.set_ylim(-5, 110);
def update(f_s=100):
line.set_ydata(fftpack.fftfreq(len(x)) * f_s)
ax.set_xlim(-f_s / 2, f_s / 2)
fig.canvas.draw()
interact(update);
给我一个错误:
ValueError Traceback (most recent call last)
<ipython-input-18-fd1aaf0ca96d> in <module>()
7
8 fig, ax = plt.subplots()
----> 9 line, = ax.stem(freqs, np.abs(X))
10 ax.set_xlabel('Frecuency [Hz]')
11 ax.set_ylabel('Spectrum')
ValueError: too many values to unpack (expected 1)
解决方案
我认为您想要展示的内容首先存在问题。如果您更改频率,您可能还需要重新计算频谱。因此,让我们首先使用折线图来纠正它。
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
from ipywidgets import *
def func(f_s):
t = np.linspace(0, 2, 2 * f_s, endpoint=False)
x = np.sin(f * 2 * np.pi * t)
X = fftpack.fft(x)
freqs = fftpack.fftfreq(len(x)) * f_s
return freqs, np.abs(X)
f = 10
f_s = 100
fig, ax = plt.subplots()
line, = ax.plot(*func(f_s), marker="o")
ax.set_xlabel('Frecuency [Hz]')
ax.set_ylabel('Spectrum')
ax.set_xlim(-f_s / 2, f_s / 2)
ax.set_ylim(-5, 110);
def update(f_s=100):
if f_s > 0:
x, y = func(f_s)
line.set_data(x, y)
ax.set_xlim(-f_s / 2, f_s / 2)
ax.set_ylim(None, 1.1*y.max())
fig.canvas.draw()
interact(update);
现在stem
绘图的问题是它会创建很多需要更新的线条。所以我宁愿推荐使用LineCollection
.
%matplotlib notebook
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
import numpy as np
from scipy import fftpack
from ipywidgets import *
def func(f_s):
t = np.linspace(0, 2, 2 * f_s, endpoint=False)
x = np.sin(f * 2 * np.pi * t)
X = fftpack.fft(x)
freqs = fftpack.fftfreq(len(x)) * f_s
return freqs, np.abs(X)
f = 10
f_s = 100
fig, ax = plt.subplots()
x,y = func(f_s)
markers, = ax.plot(x,y, ls="none", marker="o")
baseline = ax.axhline(0, color="crimson")
verts=np.c_[x, np.zeros_like(x), x, y].reshape(len(x),2,2)
col = LineCollection(verts)
ax.add_collection(col)
ax.set_xlabel('Frecuency [Hz]')
ax.set_ylabel('Spectrum')
ax.set_xlim(-f_s / 2, f_s / 2)
ax.set_ylim(None, 110);
def update(f_s=100):
if f_s > 0:
x, y = func(f_s)
markers.set_data(x, y)
verts=np.c_[x, np.zeros_like(x), x, y].reshape(len(x),2,2)
col.set_segments(verts)
ax.set_xlim(-f_s / 2, f_s / 2)
ax.set_ylim(None, 1.1*y.max())
fig.canvas.draw_idle()
interact(update);
推荐阅读
- javascript - 将组件状态传递给 next.js 中应用程序的所有组件的 Props 替代方法
- javascript - React bootstrap navbar 不会显示在 1 行
- sql - 如何将一系列存储过程合并到一个更大的存储过程中
- html - min-height 父级的子元素不尊重父级的 100% 高度
- css - 代码更改后,Vue JS CSS 未在浏览器上更新
- ios - React Native Xcode WebRTC 在发布模式下不编译
- matplotlib - GeoViews:将 matplotlib 样式参数应用于多边形元素
- java - JavaNativeFoundation.framework 在 Azul 和 Liberica JDK 中没有主要版本——我怎么能告诉 Java 使用它呢?
- android - Android InvalidBundleException:没有模块的捆绑包
- haskell - Haskell中字符串列表的长度