본문 바로가기

InfoGraph/파이썬 matplotlib 애니메이션

03. [예제]흐르는 물결같은 사인파(사인 그래프, sine graph) 그리기

반응형

 

아래 영상처럼, 물결이 흐르는 듯한 그래프를 만들어 볼 것이다.

 

 

원리는 간단하다. 사인 함수에서 $\sin {(x-a)}$는 $\sin x$의 그래프를 $a$만큼 오른쪽으로 이동한 것과 같다는 원리를 이용.

 

 


핵심 코드는 update 함수 안에 있다.

def update(i):        
    y = np.sin(x-i) # i만클 shift하는 것임
        
    line.set_data(x, y)
    
    return ln,

 

동영상의 각 프레임마다 이 update함수가 호출될 것이고, 호출될 때마다 $i$값이 1,2,3...으로 증가되어 보내질 것이다. 

 

그렇다면 그 때의 y값은 아래 그림과 같은 모양을 띨 것이고,

 

 

이 그림들을 연속으로 보여주면, 마치 파형이 이동하는 것처럼 보일 것이다.

 


전체 소스는 아래와 같다. 

 

import numpy as np
import matplotlib.pyplot as plt

from matplotlib.animation import FuncAnimation
from matplotlib import rc

fig, ax = plt.subplots(figsize=(10,6))

x, y = [], []
x = np.linspace(0, 2*np.pi, 200)
ln, = plt.plot([], [], )

def init():    
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1.2, 1.2)
    
    # X축 단위 표시를 pi 단위로 표시
    ax.set_xticks([0,np.pi/2,np.pi,(3*np.pi)/2,2*np.pi])
    ax.set_xticklabels(['0',r'$\dfrac{\pi}{2}$',r'$\pi$',r'$\dfrac{3\pi}{2}$',r'$2\pi$']) #dfrac에 유의
    
    # grid(True)를 해야 에니메이션에 grid가 나옴. 그냥 grid()는 안됨
    ax.grid(True)
      
    return ln,

def update(i):    
    # 주기: 2pi
    # y = np.sin(x-i) # i만클 shift하는 것임
    
    #  주기: pi
    y = np.sin(2*x-i) # i만클 shift하는 것임
    
    ln.set_data(x, y)
    
    return ln,

ani = FuncAnimation(fig=fig, func=update, frames=np.linspace(0, 2*np.pi, 100),
                    init_func=init, interval=20, blit=True)

rc('animation', html='html5')
ani

 

1) 앞부분에 그래프의 정적인 부분(바뀌지 않는 부분)을 지정하는 코드가 있고,

2) init 함수에서 첫 번째 프레임에 해당하는 라인을 생성하고,

3) update에서 그래프가 변화하는 부분을 코딩하고 

4) 끝으로 FuncAnimation 함수를 호출하는. 

 

이런 전형적인 구조를 띠고 있다. (이러한 구조로 작성이 된다는 것은, 앞 글에서 설명했었다. 이러한 구조가 익숙하지 않다면 앞 글을 읽기 바람)

 

   앞 글:  02. [예제]사인 곡선(사인 그래프, sine graph) 그리기

 


주피터 노트북에서 위 코드를 실행하면, 소스코드에 있는 아래와 같은 코드에 의해서 몇 초 후에 애니메이션이 자동으로 실행될 것이다. (물론 앞 장에서 설명했듯이 ffmpeg 프로그램이 미리 설치되어 있어야 한다.)

 

rc('animation', html='html5')
ani

 


만약 gif 파일로 저장하려면 다음과 같은 코드를 사용하면 된다. (ImageMagic이란 프로그램이 미리 설치되어 있어야 한다.)

ani.save('a.gif', writer='imagemagick', fps=15, dpi=100)

 

-끝-

반응형