chart.js 코드 정리

MIT 라이선스인 chart.js를 예제를 통해 간단하게 정리해 봅니다. 구현하고자 하는 모습은 아래의 영상과 같습니다.

꺽은선 차트이며, 2개의 데이터 축을 가지고 1초마다 데이터가 변경됩니다.

먼저 DOM 구조입니다.

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div>
    <canvas id="chart"></canvas>
</div>

CSS는 다음과 같구요.

@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap');

body {
    margin: 0;
    padding: 0;
}

div {
    width: 600px;
    height: 400px;
    padding: 20px;
}

이제 JS 코드에 대한 내용인데, 먼저 차트를 위한 기본 골격은 다음과 같습니다.

Chart.defaults.font.family = 'Noto Sans KR';

const ctx = document.getElementById('chart');

const config = {
    // CORE PART !!
};

const chart = new Chart(ctx, config);

위의 config에 속성값을 지정함으로써 차트를 정의하는 세세한 내용을 결정할 수 있습니다. config에 대한 속성값은 다음과 같이 정의했습니다.

const config = {
    type: 'line',
    data: {
        labels: ['빨강', 'Blue', 'Yellow', '초록', 'Purple', '오렌지'],
        datasets: [
            {
                label: '변곡점1',
                data: [12, 19, 3, 5, 2, 3],
                backgroundColor: 'yellow',
                borderColor: 'black',
                borderWidth: 1
            },
            {
                label: '변곡점2',
                data: [10, 16, 7, 6, 4, 2],
                backgroundColor: 'white',
                borderColor: 'gray',
                borderWidth: 1
            }
        ]
    },
    options: {
        maintainAspectRatio: false,
        plugins: {
            title: {
                display: true,
                text: '차트, 그것이 알고 싶다.'
            }
        },
        scales: {
            x: {
                title: {
                    display: true,
                    text: '색상'
                }
            },
            y: {
                title: {
                    display: true,
                    text: '변곡량'
                }
            }
        },

    }
}

앞서 실행 화면을 보면 1초마다 차트의 값이 변경되는 것을 볼 수 있습니다. 이에 대한 코드는 다음과 같습니다.

setInterval(() => {
    const datasets = config.data.datasets;

    for (let iDataset = 0; iDataset < datasets.length; iDataset++) {
        const data = datasets[iDataset].data;
        for (let iValue = 0; iValue < data.length; iValue++) {
            data[iValue] += Math.random() * 2.0 - 1.0;
        }
    }

    chart.update();
}, 1000);

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