본문 바로가기
파이썬

움직이는 차트, 실시간 변하는 차트 그리기

by hustler78 2022. 6. 26.
728x90
반응형

 

파이썬에서 차트를 그리다 보면 실시간 변하면서 움직이는 차트를 그리고 싶을 때가 있습니다.

이럴 때 쓰는 것이 바로 다음의 함수입니다.

matplotlib.pyplot.pause

입니다. 

interval이라는 변수를 input으로 받고, interval 초 동안 GUI event loop를 돌리면서 차트의 업데이트를 늦추는 기능을 합니다. 자세항 사항은 matplotlib totorial 을 참고하시면 됩니다.


 

 

예제 1.  2차원 Random walk 실시간으로 그리기. 

 

2022.06.25 - [수학의 재미/확률분포] - 술 먹고 걷기(Random Walk) #2: 동서남북 내키는 대로~

 

술먹고 걷기(Random Walk) #2: 동서남북 내키는대로~

지난 글에서 길 따라 걷는 1차원적인 random walk에 대해서 알아봤습니다. 2022.06.25 - [수학의 재미/확률분포] - 술 먹고 걷기(Random Walk) #1: 길 따라 걷기 술먹고 걷기(Random Walk) #1: 길따라 걷기 지난..

sine-qua-none.tistory.com

여기서 Random Walk에 대한 내용을 다뤘었는데, 술 취한 양반이 동서남북으로 랜덤 하게 움직였을 때, 어디에 도착하는지를 알아봤었습니다.  간단히 복습해보면  동서를 나타내는 확률변수를 X 가 1,-1의 값을, 남북을 나타내는 확률변수가 1, -1의 값을 가진다고 모델링을 하고, 확률이 아래와 같이 frac14라고 합시다,

 

(X,Y) (1,0) (-1,0) (0,1) (0,-1)
확률 14 14 14 14
방향

그리고 (X1,Y1),(X2,Y2),cdots(X,Y)의 i.i.d 라고 합시다. (X,Y)의 평균은 0 즉, 원점입니다. 이 때,

Ni=1(Xi,Yi)

를 하면 바로 이것이 2차원 random walk 가 됩니다.

 

실시간 그래프를 위하여 아래와 같이 코딩합니다.

 

import numpy as np
import matplotlib.pyplot as plt

def random_walk_moving():

    nSteps = 1000

    x = []
    y = []
    x0, y0 = 0, 0
    x.append(x0)
    y.append(y0)
    a, b = x0, y0

    for _ in range(nSteps):
        rd = np.random.randint(1, 5)
        if rd == 1:
            a += 1
            b += 1
        elif rd == 2:
            a += -1
            b += 1
        elif rd == 3:
            a += 1
            b += -1
        else:
            a += -1
            b += -1
        x.append(a)
        y.append(b)
        plt.plot(x,y)
        plt.pause(0.01)

if __name__ == '__main__':

    random_walk_moving()

 

다른 건 Random Walk 블로그에서 설명을 볼 수 있고, Random walk 진행을 나타내는 변수 x,y를 갱신하면서

 

        plt.pause(0.01)

를 썼습니다. 즉, 0.01 초동안 그래프의 갱신을 pause 하라는 이야기죠. 결과를 볼까요?

 

 

정처없이 움직이는 술취한 나그네

 


예제 2. 푸리에 급수 관찰하기

sawtooth function이라는 함수가 있습니다.

s(x)=xπ  ,  π<x<πs(x+2πk)=s(x)  ,  π<x<π,kZ

인데요, 이름에서도 느껴지지만 함수 모양 자체가 톱니(sawtooth)처럼 생겼습니다. 주파수 같은 파동을 다루는 이론에서 긴요하게 쓰인다고 알고 있습니다.

 

이 함수를 푸리에 급수(즉, sin, cos 함수를 이용한 무한급수) 형태로 표시하면 아래와 같습니다.

 

s(x)=2πn=1(1)n+1nsin(nx)

 

즉 

sn(x)=2π(1)n+1nsin(nx)

이라 하면, 

s(x)=n=1sn(x)

라는 얘기죠.

과연 맞는지 coding을 통해 알아보겠습니다.

 

import numpy as np
import matplotlib.pyplot as plt

def draw_FourierSeries():
    x = np.arange(-5 * np.pi, 5 * np.pi, 0.01)
    y = np.zeros(len(x))
    coeff = 0
    for n in range(1, 100):
        coeff = (-1) ** (n + 1) / n
        y += np.sin(n * x) * coeff * 2 / np.pi
        plt.plot(x, y)
        plt.pause(1)
        # plt.cla()

if __name__ == '__main__':
    draw_FourierSeries()

○ x 는 [5π,5π] 구간을 나타냅니다. 0.01 단위로 쪼갰습니다.

sn 을 계산하여 y라는 변수에 계속 더해갑니다.

○ 그래프 변화를 관찰하기 위해 1초 동안 pause 합니다 

○ 우선 plt.cla() 는 주석처리합니다.

 

 

결과를 보실까요?

톱니를 만들어 봅시다.

 

결과가 중첩되니까 약간 지저분해 보이죠? 따라서 이전의 함수 그래프를 지우기 위해

        plt.cla()

를 사용합니다. 그러면 결과는 아래처럼 보입니다.

깔끔한 톱니를 만들어봅시다.

 

참고로

matplotlib.pyplot.cla
Clear the current axes.

입니다.

 

이처럼 pause를 이용해 움직이는 차트를  그릴 수 있습니다. 시각화에 대한 자신감이 좀 더 생기겠네요.

728x90
반응형

'파이썬' 카테고리의 다른 글

여러개의 그래프를 한 번에 그리는 예제  (0) 2023.04.05
randint를 사용할 땐 주의하라고?  (0) 2022.06.27