본문 바로가기

Javascript/Chart.js

ChatGPT로 Chart.js 알아보기 (9):산점도(Scatter Chart)

반응형

ChatGPT로 Chart.js 알아보기 (9):산점도(Scatter Chart)

이번 포스트에서는 ChatGPT로 Chart.js의 산점도(Scatter Chart)를 생성하는 방법에 대해 알아보겠다.
우선 산점도가 무엇인지 알아보고 Chart.js의 예시를 보면서 사용방법에 대해 알아보자.
산점도(Scatter Chart)란?
산점도(Scatter chart)는 두 변수 사이의 관계나 트렌드를 시각적으로 나타낼 때 사용된다.
이 차트는 가로축과 세로축에 대응하는 두 변수의 값을 점으로 표시하여 각 점들이 분포된 패턴을 통해 두 변수 간의 상관 관계를 나타낸다.
두 변수 사이에 어떤 관계가 있는지, 그 관계가 어떤 경향을 보이는지를 시각적으로 이해하는 데 매우 유용하다.
또한, 이상치 검출에도 효과적이며, 데이터의 분포와 밀도를 한 눈에 파악할 수 있다.
예를 들어, 회사에서 매출과 광고 비용 사이의 관계를 분석하고 싶다면, 가로축에 광고 비용을, 세로축에 매출을 놓고 각각의 시점에서의 광고 비용과 매출을 점으로 표시하면, 광고 비용이 증가함에 따라 매출이 어떻게 변화하는지 쉽게 파악할 수 있다.

사용할 때 주의할 점은, 산점도는 두 변수 사이의 상관관계만을 나타내며 이는 인과관계를 의미하지 않는다는 점이다.
예를 들어, 매출이 높은 날은 광고 비용도 높은 경향이 있다면, 이는 광고 비용과 매출 사이에 상관관계가 있다는 것을 보여주지만, 광고 비용이 매출을 높이는 원인이라고 단정지을 수는 없다.
Scatter Chart 생성
Chart.js로 산점도를 생성하려면 type을 scatter로 주면 된다.
type: 'scatter'
산점도를 만들 때 dataset은 x축의 값, y축의 값으로 구성해야한다.
x는 x축의 값, y는 y축의 값을 나타낸다.
이 값들은 각 점의 위치를 결정하게 된다.
data: [{
    x: 5,
    y: 10
}, {
    x: 15,
    y: -10
}, {
    x: -10,
    y: 20
}, ...]
위에서 생성한 산점도의 전체 코드는 아래와 같다.
const exampleCtx = document.querySelector('#scatterExample').getContext('2d');
const scatterChartExample = new Chart(exampleCtx, {
    type: 'scatter',
    data: {
        datasets: [{
            label: 'Scatter Dataset',
            data: [{
                x: -10,
                y: 0
            }, {
                x: 0,
                y: 10
            }, {
                x: 10,
                y: 5
            }, {
                x: 15,
                y: -10
            }],
            backgroundColor: 'rgba(255, 99, 132, 0.6)'
        }]
    },
    options: {
        scales: {
            x: {
                beginAtZero: true
            },
            y: {
                beginAtZero: true
            }
        }
    }
});
예시
산점도는 두 변수 사이의 관계를 시각적으로 나타내기 때문에, 다양한 분야에서 활용될 수 있다.
활용 예시와 함께 scatter type에 사용할 수 있는 몇가지 옵션에 대해서도 함께 알아보자.
✔ 경제학과 비즈니스 분석
경제학과 비즈니스 분야에서는 종종 두 가지 변수 사이의 상관관계를 파악하는 데 산점도를 활용한다.
예를 들어, 회사는 광고 지출과 판매량 사이의 관계를 확인하기 위해 산점도를 사용할 수 있다.
Chart.js로 광고지출과 판매량에 대한 산점도를 만들어보고, hover 옵션들을 사용해서 포인트에 몇가지 효과를 추가해보겠다.
광고 지출과 판매량 사이의 관계에 대한 산점도를 만들어 보았다.
또한 이번 산점도에서는 포인트의 radius를 조금 더 크게 해주고, hover 효과를 변경해보았다.
이 차트에서 사용한 옵션은 아래와 같다.
options: {
    pointRadius: 7,
    pointBackgroundColor: 'rgba(16, 163, 127, 0.5)',
    pointHoverBackgroundColor: 'rgba(16, 163, 127, 0.7)',
    pointHoverBorderColor: 'rgba(16, 163, 127, 1)',
    pointHoverBorderWidth: 4,
    pointHoverRadius: 12,
}
옵션 설명
pointRadius 데이터 포인트의 반경을 설정
pointBackgroundColor 데이터 포인트의 배경색을 설정
pointHoverBackgroundColor 마우스가 데이터 포인트 위에 있을 때의 배경색을 설정
pointHoverBorderColor 마우스가 데이터 포인트 위에 있을 때의 테두리 색을 설정
pointHoverBorderWidth 마우스가 데이터 포인트 위에 있을 때의 테두리 두께를 설정
pointHoverRadius 마우스가 데이터 포인트 위에 있을 때의 반경을 설정
const adCtx = document.querySelector('#adChart').getContext('2d');
const adChart = new Chart(adCtx, {
    type: 'scatter',
    data: {
        datasets: [{
            label: '광고 지출 vs 판매량',
            data: [
                {x: 500, y: 2500},
                {x: 1000, y: 5000},
                {x: 1500, y: 7500},
                {x: 2000, y: 8000},
                {x: 2500, y: 9000},
                {x: 3000, y: 11000},
                {x: 3500, y: 12000},
                {x: 4000, y: 14000},
                {x: 4500, y: 16000},
                {x: 5000, y: 18000},
            ],
        }]
    },
    options: {
        pointRadius: 7,
        pointBackgroundColor: 'rgba(16, 163, 127, 0.5)',
        pointHoverBackgroundColor: 'rgba(16, 163, 127, 0.7)',
        pointHoverBorderColor: 'rgba(16, 163, 127, 1)',
        pointHoverBorderWidth: 4,
        pointHoverRadius: 12,
        scales: {
            x: {
                title: {
                    display: true,
                    text: '광고 지출 (단위: $)'
                }
            },
            y: {
                title: {
                    display: true,
                    text: '판매량'
                }
            }
        }
    }
});
✔ 의료 및 공중 보건
의료 및 공중 보건 분야에서는 산점도를 사용하여 두 가지 변수 사이의 상관관계를 살펴봄으로써 특정 요인이 건강에 어떤 영향을 미치는지 이해하려고 한다.
예를 들어, 연구자들은 체중과 특정 건강 지표(혈압, 콜레스테롤 수치 등) 사이의 관계를 파악하기 위해 산점도를 사용할 수 있다.

이번에는 나이와 혈압에 대한 데이터로 산점도를 만들어보고, 선형 회귀 함수 데이터를 추가해서 선형회귀선을 그려보겠다.
사실 산점도에 대한 옵션이 아닌 다음에 포스팅할 Mixed Chart Types에 해당되는 내용인데, 산점도 하면 선형회귀선이 생각나서 작성해보았다.
필자의 경우 전공이 통계학과였는데, 사실 너무 오랜만에 본다...
이렇게 차트에 다른 type의 차트를 추가해줄려면 datasets에 넣는 데이터의 type을 선언해주면 된다.
data: {
    datasets: [{
        label: '실제값',
        data: healthData,
        backgroundColor: 'rgba(17, 152, 247, 0.6)',
        borderColor: 'rgba(17, 152, 247, 1)',
        pointRadius: 5
    },
    {
        label: '선형회귀선',
        data: healthLRData,
        type: 'line',
        fill: false,
        borderColor: 'rgba(245, 53, 133, 0.6)',
        backgroundColor: 'rgba(245, 53, 133, 1)',
        pointRadius: 0,
        showLine: true,
        lineTension: 0
    }]
}
위 코드처럼 datasets에 들어가는 객체에서 '선형회귀선'의 경우 type이 line으로 선언되어 있는 것을 볼 수 있다.
이렇게 Chart.js에서는 datasets의 데이터 객체에 type을 변경해주면 혼합 차트를 생성할 수 있다.
아래는 선형회귀선 데이터를 만들기 위한 함수인데 참고용으로 함께 작성했다.
function linearRegression(y, x) {
    let lr = {};
    let n = y.length;
    let sum_x = 0;
    let sum_y = 0;
    let sum_xy = 0;
    let sum_xx = 0;
    let sum_yy = 0;

    for (let i = 0; i < y.length; i++) {
        sum_x += x[i];
        sum_y += y[i];
        sum_xy += (x[i]*y[i]);
        sum_xx += (x[i]*x[i]);
        sum_yy += (y[i]*y[i]);
    }

    lr['slope'] = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
    lr['intercept'] = (sum_y - lr['slope'] * sum_x) / n;

    return lr;
}
아래는 위 차트의 전체 코드이다.
const healthData = [
    {x: 22, y: 123}, {x: 24, y: 127}, {x: 26, y: 121}, {x: 28, y: 122}, {x: 29, y: 120},
    {x: 32, y: 130}, {x: 35, y: 135}, {x: 36, y: 140}, {x: 38, y: 136}, {x: 40, y: 139},
    {x: 43, y: 140}, {x: 45, y: 143}, {x: 46, y: 145}, {x: 48, y: 149}, {x: 50, y: 151},
    {x: 52, y: 155}, {x: 55, y: 157}, {x: 57, y: 158}, {x: 59, y: 160}, {x: 60, y: 161},
    {x: 62, y: 162}, {x: 65, y: 163}, {x: 67, y: 164}, {x: 68, y: 165}, {x: 70, y: 166},
    {x: 73, y: 168}, {x: 75, y: 170}, {x: 76, y: 172}, {x: 78, y: 174}, {x: 80, y: 176},
    {x: 22, y: 125}, {x: 27, y: 127}, {x: 22, y: 126}, {x: 23, y: 129}, {x: 21, y: 121},
    {x: 32, y: 135}, {x: 37, y: 135}, {x: 32, y: 146}, {x: 33, y: 139}, {x: 41, y: 131},
    {x: 43, y: 145}, {x: 47, y: 143}, {x: 42, y: 146}, {x: 43, y: 149}, {x: 51, y: 151},
    {x: 52, y: 155}, {x: 57, y: 157}, {x: 52, y: 156}, {x: 53, y: 169}, {x: 61, y: 161},
    {x: 62, y: 165}, {x: 67, y: 163}, {x: 62, y: 166}, {x: 63, y: 169}, {x: 71, y: 161},
    {x: 73, y: 165}, {x: 77, y: 170}, {x: 72, y: 176}, {x: 73, y: 179}, {x: 81, y: 171}
];

let healthLR = linearRegression(healthData.map(d => d.y), healthData.map(d => d.x));

let healthLRData = healthData.map(d => ({
    x: d.x,
    y: healthLR.slope * d.x + healthLR.intercept
}));

const healthCtx = document.querySelector('#healthChart').getContext('2d');
const healthChart = new Chart(healthCtx, {
    type: 'scatter',
    data: {
        datasets: [{
            label: '실제값',
            data: healthData,
            backgroundColor: 'rgba(17, 152, 247, 0.6)',
            borderColor: 'rgba(17, 152, 247, 1)',
            pointRadius: 5
        },
        {
            label: '선형회귀선',
            data: healthLRData,
            type: 'line',
            fill: false,
            borderColor: 'rgba(245, 53, 133, 0.6)',
            backgroundColor: 'rgba(245, 53, 133, 1)',
            pointRadius: 0,
            showLine: true,
            lineTension: 0
        }]
    },
    options: {
        scales: {
            x: {
                title: {
                    display: true,
                    text: '나이'
                },
                max: 85
            },
            y: {
                title: {
                    display: true,
                    text: '혈압'
                }
            }
        }
    }
});
이번 포스트에서는 ChatGPT로 Chart.js로 산점도를 만드는 방법에 대해 공부해 보았다.
전공이 통계학과였어서 상당히 오랜만에 회귀분석, 선형회귀 등의 용어를 들었을 때 상당히 반가웠다.
지금 결국은 통계학 관련된 업무를 하곤 있진 않지만 개인적으로 통계학은 상당히 매력적인 학문이라고 생각한다.
ChatGPT로 Python의 pandas와 Chart.js도 공부해 보면서 통계학에 관련된 내용도 ChatGPT로 공부해 볼까...라는 생각이 들었다.
커피 한 잔으로
저를 응원해주세요!
반응형

loading