matplotlib에서 애니메이션 그래프 표현하기

matplotlib는 다양한 그래프를 표현할 수 있는데요. 정적인 그래프 뿐만 아니라 데이터가 실시간으로 변경되면 그에 대한 동적인 그래프도 표현할 수 있습니다. 아래는 예시로써 그 결과입니다.

위의 예시를 실제로 구현하기 위한 코드를 살펴 보겠습니다. 이를 위해 먼저 그래프로 표현하기 위한 데이터가 필요한데, 아래의 코드는 데이터를 구성하는 코드입니다.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

data = np.random.uniform(0, 1, (64, 75))
X = np.linspace(-1, 1, data.shape[-1])
G = 1.5 * np.exp(-4 * X ** 2)

예시의 결과를 보면, 65개의 꺽은선 그래프로 구성되어 있습니다. 아래는 이 꺽은선 그래프를 구성하는 코드입니다.

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 8))
ax = plt.subplot(111, frameon=False)

lines = []
for i in range(data.shape[0]):
    xscale = 1 - i / 200.0
    lw = 1 - i / 100.0
    line, = ax.plot(xscale * X, i + G * data[i], color="k", lw=lw)
    lines.append(line)

이제 최종적으로 데이터를 0.2초마다 변경하고, 변경된 데이터에 대한 그래프를 업데이트하면서 마치 동적으로 그래프가 움직이는 효과를 내는 코드를 살펴 보겠습니다.

import matplotlib.animation as animation

ax.set_xticks([])
ax.set_yticks([])

ax.text(0.5, 1.0, "MATPLOTLIB ", transform=ax.transAxes, ha="right", va="bottom", color="k", 
        family="sans-serif", fontweight="bold", fontsize=16)
ax.text(0.5, 1.0, "DYNAMIC", transform=ax.transAxes, ha="left", va="bottom", color="k",
        family="sans-serif", fontweight="light", fontsize=20)

def update(*args):
    data[:, 1:] = data[:, :-1]
    data[:, 0] = np.random.uniform(0, 1, len(data))

    for i in range(len(data)):
        lines[i].set_ydata(i + G * data[i])

anim = animation.FuncAnimation(fig, update, interval=200)
plt.show()

matplotlib의 등치선(contour) 표현하기

등치선은 공간상에 분포하는 동일한 값을 가지는 인접한 지점을 연속적으로 이어 구성한 선입니다. 대기 확산 모델을 시각화하기 위한 매우 효과적인 방법입니다.

아래의 그림은 contour 그래프를 구성하기 위한 코드로써 작성한 예제에 대한 결과입니다.

위의 결과를 위해서는 먼저 시각화 대상이 되는 데이터가 필요합니다. 공간상에 균일하게 분포하는 값에 대한 데이터인데요. 데이터 구성을 위한 코드는 다음과 같습니다.

import matplotlib.pyplot as plt
import matplotlib.tri as tri
import numpy as np

npts = 100
x = np.random.uniform(-2, 2, npts)
y = np.random.uniform(-2, 2, npts)
z = x * np.exp(-x**2 - y**2)

ngridx = 100
ngridy = 100
xi = np.linspace(-2.2, 2.2, ngridx)
yi = np.linspace(-2.2, 2.2, ngridy)

triang = tri.Triangulation(x, y)
interpolator = tri.LinearTriInterpolator(triang, z)
Xi, Yi = np.meshgrid(xi, yi)
zi = interpolator(Xi, Yi)

위의 코드를 통해 2차원(x, y) 공간 상에 분포하는 값(z)으로 변수 xi, yi, zi를 얻게 됩니다. 이 3개의 변수를 이용해 등치선을 표현할 수 있는데, 그 코드는 다음과 같습니다.

plt.contour(xi, yi, zi, levels=15, linewidths=0.5, colors='k')

cntr = plt.contourf(xi, yi, zi, levels=15, cmap="RdBu_r")
plt.colorbar(cntr)
plt.plot(x, y, 'ko', ms=3)

plt.show()

위의 코드 중 1번이 지정한 levels 수에 맞게 등치선(검정색 선)을 표현하며, 3번 코드는 등치값들을 포함하는 영역을 지정한 levels 수에 맞게 표현하는 코드입니다.