いぬおさんのおもしろ数学実験室

おいしい紅茶でも飲みながら数学、物理、工学、プログラミング、そして読書を楽しみましょう

pythonでリアルタイムに動くグラフを描く

 Pythonのmatplotlibでグラフを描画するのは便利で易しいのですが、普通にshow()で描画するとそこでいったん止まってしまいます。時間を追って変化するグラフは描けません。調べるとpause()というのがあるようで、試してみました。plt.show(0.1)の行です。描画して0.1秒間止まり、次に移ります。3角関数の角をじわじわ変えています。
 コードはほぼ最小限度の量なので、分かりやすいと思います。
#-----------------------------------------
#リアルタイムにグラフを描画
#

import sys
import numpy as np
import matplotlib.pyplot as plt
pi = np.pi
t = np.arange(0, 3, 1/40) #横軸
for i in range(1,1000):
    plt.ylim(-5, 5) #y軸の最小値、最大値をセット
    y = 3*np.sin(2*pi*4*t+0.3*i)
    plt.plot(t, y) #波形を描画
    plt.pause(0.1) #pyplot.show()では1回描画して止まってしまう
    plt.clf() #今描いたグラフを消す
sys.exit()

 ついでに、時間が経つと周波数成分が変わる様子も見てみました。すでにこのブログで、決まった式から周波数成分を求めて描画するコードを紹介しています。今回は3角関数の角を少しずつ変え、そのたびにFFTを実行して周波数成分を求めて描画、とやっています。こちらもコードは多分ほぼ最小限です。
#-----------------------------------------
#リアルタイムに周波数成分を描画
#

import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
import matplotlib.pyplot as plt
pi = np.pi
N = 120    #データ数は3/(1/40)=120
# t は1/40秒刻みの時刻の配列。基本周期T = 3秒。基本周波数=1/3Hz。
t = np.arange(0, 3, 1/40)
for i in range(1,1000):
    plt.ylim(0, 5) #y軸の最小値、最大値をセット
    y = np.sin(2*pi*(0.001*i)*t)+np.sin(2*pi*(0.03*i)*t)
    yf = sp.fftpack.fft(y[:N])
#yf[k]には第k次高調波のフーリエ係数が入る
    plt.plot(np.abs(yf))    #含まれる周波数成分を描画
    plt.pause(0.1)
    plt.clf()
sys.exit()

f:id:Inuosann:20191224214254p:plain:w300

 ここまで少しPythonで実験してきました。近々、waveファイルの音楽から周波数成分を求めて高音域をカットしてwaveファイルを保存する、とやってみたいと考えています。waveファイルを扱うためのwaveというモジュールがあります。試します。