【问题标题】:Oscilloscope animation of an electric signal in PythonPython中电信号的示波器动画
【发布时间】:2020-10-12 18:45:42
【问题描述】:

晚上好, 我是 Python 新手。我正在尝试处理保存在 npy 文件中的信号。
该文件包含一个电信号,我想像在实验室中使用示波器一样查看它,因此我想生成一个动画,向我展示信号如何随时间变化。
这是我的尝试:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

signal = np.load('signal.npy')

fig = plt.figure()

def animation(i):
    plt.cla()
    plt.plot(signal)
    # what to do here?

anim = FuncAnimation(fig, animation, frames = len(signal), interval = 10)
plt.show()

我不知道在动画功能中做什么。
提前感谢,对不起我的英语

【问题讨论】:

    标签: python matplotlib animation signals signal-processing


    【解决方案1】:

    matplotlib 文档中,您可以看到一个示波器模拟示例here

    【讨论】:

      【解决方案2】:

      由于我无权访问您的信号数据,因此我生成了我的信号数据以运行动画。用你的替换我的随机信号。
      根据时间查看信号的基本代码可能是这样的:

      # import
      import numpy as np
      import matplotlib.pyplot as plt
      from matplotlib.animation import FuncAnimation
      
      # signal generation
      N = 10001
      stop = 100
      time = np.linspace(0, stop, N)
      A = 1/4*np.cos(2*np.pi*(np.abs(time - stop/2)/stop)) + 1
      f = np.concatenate((1*np.ones(int(N/4)), 2*np.ones(int(N/2) + 1), 1*np.ones(int(N/4))))
      signal = A * np.sin(2*np.pi*f*time) + 0.05*np.random.randn(N)
      
      # figure preparation
      fig, ax = plt.subplots(1, 1, figsize = (8*0.9, 6*0.9))
      displayed_period = int(2*f.min())
      span = int(N/stop/f.min())
      
      def animation(i):
          # delete previous frame
          ax.cla()
      
          # plot and set axes limits
          ax.plot(time[span*i: 1 + span*(i + displayed_period)],
                  signal[span*i: 1 + span*(i + displayed_period)])
          ax.set_xlim([time[span*i], time[span*(i + displayed_period)]])
          ax.set_ylim([1.1*signal.min(), 1.1*signal.max()])
      
      # run animation
      anim = FuncAnimation(fig, animation, frames = int(len(time)/span - 1), interval = 10)
      plt.show()
      

      给出这个动画:

      说明

      在我的例子中,信号是一个正弦波,它会随着时间的推移改变幅度和频率(加上一些噪声)。我选择在每一帧看到我的信号的两个完整振荡,所以我设置了

      displayed_period = int(2*f.min())
      

      确保至少看到两个完整的振荡。然后我必须定义一个帧和以下帧之间通过x轴的时间量,所以我设置:

      span = int(N/stop/f.min())
      

      话虽如此,当您运行代码时,animation 函数被多次调用,每次i 计数器增加1。因此,您可以使用此计数器对 timesignal 数组进行切片:time[span*i: 1 + span*(i + displayed_period)]
      通过这种方式,您可以绘制displayed_period 的完整振荡次数,并且对于每一帧,您将 x 轴滚动span 元素。
      您必须根据您的信号属性设置displayed_periodspan 才能获得类似的结果。


      如果您想像示波器一样进行一些定制,请查看以下代码:

      # import
      import numpy as np
      import matplotlib.pyplot as plt
      from matplotlib.animation import FuncAnimation
      
      # signal generation
      N = 10001
      stop = 100
      time = np.linspace(0, stop, N)
      A = 1/4*np.cos(2*np.pi*(np.abs(time - stop/2)/stop)) + 1
      f = np.concatenate((1*np.ones(int(N/4)), 2*np.ones(int(N/2) + 1), 1*np.ones(int(N/4))))
      signal = A * np.sin(2*np.pi*f*time) + 0.05*np.random.randn(N)
      
      # color definition
      black = '#0F110D'
      grey = '#3B3D3A'
      yellow = '#FFFF21'
      
      # figure preparation
      fig, ax = plt.subplots(1, 1, figsize = (8*0.9, 6*0.9))
      displayed_period = int(2*f.min())
      span = int(N/stop/f.min())
      
      def animation(i):
          # delete previous frame
          ax.cla()
      
          # set background color and plot
          ax.set_facecolor(black)
          ax.plot(time[span*i: 1 + span*(i + displayed_period)],
                  signal[span*i: 1 + span*(i + displayed_period)],
                  color = yellow)
      
          # plot axes lines
          ax.hlines(y = 0,
                    xmin = 0,
                    xmax = stop,
                    lw = 2,
                    colors = grey)
          ax.vlines(x = time[int(span*i + (1 + span*displayed_period)/2)],
                    ymin = 1.1*signal.min(),
                    ymax = 1.1*signal.max(),
                    lw = 2,
                    colors = grey)
      
          # set grid, axes limits and ticks
          ax.grid(which = 'major',
                  ls = '-',
                  lw = 0.5,
                  color = grey)
          ax.set_xlim([time[span*i], time[span*(i + displayed_period)]])
          ax.set_ylim([1.1*signal.min(), 1.1*signal.max()])
          plt.tick_params(axis = 'both',
                          which = 'both',
                          bottom = False,
                          left = False,
                          labelbottom = False,
                          labelleft = False)
      
      # run animation
      anim = FuncAnimation(fig, animation, frames = int(len(time)/span - 1), interval = 10)
      anim.save('oscilloscope.gif', writer = 'imagemagick')
      plt.show()
      

      我没有改变功能,只是动画方面:

      【讨论】:

        猜你喜欢
        • 2018-11-28
        • 2015-11-17
        • 1970-01-01
        • 2019-02-11
        • 1970-01-01
        • 2017-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多