반응형

MATLAB의 drawnow는 반복문 속에서 사용되는데, 그릴 plot에 대해서 drawnow가 호출된다면 그리려고 했던 모든 plot을 다 그리게 된다. 그렇다면 매우 빠르게 계속 그려주면 움직이는 그림, 애니메이션 처럼 보일 것이다.

비슷하게 python 라이브러리 중, matplotlib를 이용한 drawnow[1] 라이브러리가 있다.

MATLAB의 drawnow와의 차이점은

MATLAB drawnow는 그리고 싶은 시점에서 그냥 선언하면 되지만,

Python drawnow 라이브러리는 사전에 plot을 그리도록 선언한 함수를 drawnow함수가 호출해야한다는 점이다.

 

1. drawnow 설치하기

python 라이브러리 drawnow를 사용하기 위해서 다음을 입력하여 설치하자.

pip install matplotlib

pip install drawnow

 

추가적으로 수학함수 사용을 위해서 numpy를 설치하자.

pip install numpy

 

2. drawnow로 움직이는 그림 그려보기

2.1. 2D Sine 함수 그리기

다음과 같이 라이브러리를 불러온다.

%matplotlib tk 줄은 backend에서 돌아가는 gui 라이브러리로 어떤 것을 사용할 지 명시한 부분이다. inline, qt5 등을 선택할 수 있다.

1
2
3
4
%matplotlib tk
import matplotlib.pyplot as plt
import numpy as np
from drawnow import *
cs

예시로 각도에 대한 sine, cosine 함수의 그래프를 그려보자.

아래 코드처럼 python drawnow는 그리고자 하는 내용을 함수로 정의해두고, 해당 함수를 호출하는 형태이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fig = plt.figure(1)
 
angles = []
sines = []
cosines = []
 
def show_plot():
    plt.plot(angles,sines,label='Sine')
    plt.plot(angles,cosines,label='Cosine')
    plt.legend()
    plt.grid()
    plt.xlabel('Angles [deg]')
    plt.ylabel('Value')
    
for x in np.linspace(0,np.pi*2,100):
    angles = np.append(angles, x)
    sines  = np.append(sines, np.sin(x))
    cosines= np.append(cosines, np.cos(x))
    
    drawnow(show_plot)
cs

결과는 다음과 같다.

Sine, Cosine 함수의 각도 별 값의 애니메이션화

 

2.2. 3D Surface 그리기, sine 함수를 이용하여 물방울 맞은 수면같은 거

대충 원점 (0,0)에서의 거리에 대해서 cosine을 취하고, 파장의 크기를 거리에 반비례한다고 하자. 그렇다면 대략 아래의 식이 나온다.

$$D = sqrt(X^2 + Y^2)$$

$$Z = cos(D+\text{time}) \frac{1}{1+D}$$

이를 바탕으로 코드를 짜면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
sizes = 101
= np.linspace(-np.pi, np.pi, sizes)
= np.tile(x,(sizes,1))
= np.transpose(X)
= np.zeros((sizes,sizes),dtype='float')
 
 
fig = plt.figure(1)
 
def show_plot():
    ax = fig.add_subplot(111,projection='3d')
    ax.plot_surface(X,Y,Z)
    ax.set_xlim((-np.pi,np.pi))
    ax.set_ylim((-np.pi,np.pi))
    ax.set_zlim((-1,1))
    pan = 30
    tilt = 60
    ax.view_init(pan,tilt)
    
for now in np.linspace(0,2*np.pi,100):
    
    for ix in range(0,sizes):
        for iy in range(0,sizes):
            dist = np.sqrt(X[ix,iy]**2 + Y[ix,iy]**2)
            Z[ix,iy] = np.cos((dist*3+now))*(1/(dist+1))
            
    drawnow(show_plot)
cs

 

그려보면 다음과 같다.

 

Tip. Ubuntu에서 움직이는 그림 gif 따는 프로그램, peek[2]

위 움직이는 그림들은 peek을 이용하여 찍었다.

아래 코드를 따라서 설치할 수 있다.

sudo add-apt-repository ppa:peek-developers/stable
sudo apt update
sudo apt install peek

 

사용방법은 간단하다.

촬영하고자 하는 영역을 지정한 후,

버튼을 눌러서 촬영 시작, 종료를 하거나

Ctrl+Shift+R 로 촬영 시작, 종료를 하거나

 

Ref.

1. drawnow for matplotlib, pypi.org/project/drawnow/

2. peek, github repo, github.com/phw/peek#ubuntu

 

 

 

728x90

+ Recent posts