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()

단순 선형 회귀에 대한 2가지 접근

잡음이 섞인 샘플 데이터가 선형이라고 가정할때, 이 선형 모델은 기울기와 절편이라는 값으로 정의됩니다. 이 기울기와 절펀에 대한 값을 구하는 방법은 다양한데, 이 글에서는 2가지 접근 방법을 언급합니다. 먼저 잡음이 섞인 샘플 데이터는 다음과 같습니다.

import numpy as np
import matplotlib.pyplot as plt

X = 10 * np.random.rand(100,1)
y = 3.7 - 2.5 * X + np.random.randn(100,1)
plt.scatter(X, y)
plt.show()

위의 코드는 샘플 데이터에 대한 시각화 코드도 포함하고 있는데, 그 결과는 다음과 같습니다.

이제 위의 샘플 데이터에 대한 선형회귀 방법 중 하나인 정규방정식(Normal Equation)에 대한 코드는 다음과 같습니다.

X_b = np.c_[np.ones((100,1)), X]
w = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
print(w)

plt.scatter(X, y)
drawLine(w[1], w[0])
plt.show()

분석된 절편과 기울기에 대한 출력 및 결과 모델의 선형은 다음과 같습니다.

[[ 3.76686801]
 [-2.50677558]]

아울러 정규방정식은 다음과 같습니다.

    $$(X^{T}X)^{-1}X^{T}y$$

다음은 사이킷런에서 제공하는 LinearRegression 클래스를 이용한 방법입니다.

from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, y)
w = [model.intercept_[0], model.coef_[0][0]]
print(w)

plt.scatter(X, y)
drawLine(w[1], w[0])
plt.show()

분석된 절편과 기울기에 대한 출력 및 결과 모델의 선형은 다음과 같습니다.

[[ 3.69686801]
 [-2.50677558]]

위의 코드에서 절편과 기울기를 통해 그래프를 그리는 함수인 drawLine은 다음과 같습니다.

def drawLine(m, b):
    X = np.arange(0, 11)
    y = [m * x + b for x in X]
    plt.plot(X, y)