【问题标题】:Is there an easy way to animate a scrolling vertical line in matplotlib?有没有一种简单的方法可以在 matplotlib 中为滚动垂直线设置动画?
【发布时间】:2020-05-14 22:01:25
【问题描述】:

我想要一个进度标记,它在音频播放实用程序中似乎很常见。我认为在 matplotlib 中这相当于左/右动画plt.vlines。我的代码需要 2 秒的数据数组并创建音频时间序列可视化。我正在努力创建一条动画垂直线,该垂直线将从 0 到 2 线性移动 2 秒。

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

font = {'weight': 'bold', 'size': 15}
plt.rc('font',**font)
sns.set_style("darkgrid")

testSeries = np.random.randint(-10, 20, 12000)
testSeries = testSeries - testSeries.mean()


fig,axis = plt.subplots(nrows=1,ncols=1,figsize=(18,5),sharex=True)
sns.lineplot(range(0,len(testSeries)),testSeries,  color='#007294')
plt.xlim(0, len(testSeries))
axis.set_xlabel("Time (s)", fontsize='large', fontweight='bold')
axis.set_ylabel("Amplitude", fontsize='large', fontweight='bold')
axis.set_xticklabels(['0', '0.3', '0.6', '1', '1.3', '1.6', '2'],fontsize=15)
fig.tight_layout(rect=[0,0,.8,1]) 
plt.subplots_adjust(bottom=-0.01)
sns.despine()
plt.show()

【问题讨论】:

    标签: python matplotlib animation seaborn


    【解决方案1】:

    axvline() 只返回一个Line2D 对象,因此您可以使用Line2D.set_xdata() 更新其位置

    duration = 2 # in sec
    refreshPeriod = 100 # in ms
    
    fig,ax = plt.subplots()
    vl = ax.axvline(0, ls='-', color='r', lw=1, zorder=10)
    ax.set_xlim(0,duration)
    
    def animate(i,vl,period):
        t = i*period / 1000
        vl.set_xdata([t,t])
        return vl,
    
    ani = animation.FuncAnimation(fig, animate, frames=int(duration/(refreshPeriod/1000)), fargs=(vl,refreshPeriod), interval=refreshPeriod)
    plt.show()
    

    请注意,刷新率并不能保证,它取决于重绘图形所需的时间。您可能不得不使用refreshPeriod

    【讨论】:

      【解决方案2】:

      matplotlib 的交互模式可能对你有用。设置方法如下:

      import numpy as np
      import matplotlib.pyplot as plt
      import numpy as np
      
      
      testSeries = np.random.randint(-10, 20, 1000)
      testSeries = testSeries - testSeries.mean()
      
      x = range(0,len(testSeries))
      fig,ax = plt.subplots(nrows=1,ncols=1)
      
      line = ax.plot((x[0], x[0]), (0, testSeries[0]), 'k-',linewidth=4)
      
      plt.xlim(0, len(testSeries))
      plt.ion()   # set interactive mode
      plt.show()
      
      ax.set_xlabel("Time (s)", fontsize='large', fontweight='bold')
      ax.set_ylabel("Amplitude", fontsize='large', fontweight='bold')
      ax.set_xticklabels(['0', '0.3', '0.6', '1', '1.3', '1.6', '2'],fontsize=15)
      
      for i,serie in enumerate(testSeries):
      #comment the following three lines if you don't want to remove previous lines
      
          for l in line:
              l.remove()
              del l
      
          line = ax.plot((x[i], x[i]), (0, testSeries[i]), 'k-',linewidth=4)
          plt.gcf().canvas.draw()
          plt.pause(0.01)
      

      输出(保留前几行):

      输出(删除前几行):

      【讨论】:

      • 这并不是我想要实现的目标,但它仍然是一个有趣的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2017-03-03
      • 2011-05-12
      • 2021-02-13
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多