↓폴밍끼 유튜브 채널 자세히보기

FRAME WORK/Flask

flask로 만든 변수를 chart.js 에 적용하는 방법

폴밍끼 2021. 7. 26. 13:08
728x90

이 글은 flask로 chart.js를 적용해서 만드는데 html부분에 변수 적용이 어려웠던 저의 경험을 나누고자 작성되었습니다.

아래는 https://www.chartjs.org/docs/latest/ 에서 제공하고 있는 예시인데요,

<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
        datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            y: {
                beginAtZero: true
            }
        }
    }
});
</script>

 이 코드의 결과물은 아래와 같고요,

디자인이 넘 이쁘죠?

웹에 chart.js를 띄울 때 보통 labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange']이 부분(x축 라벨)과, datasets의 data: [12, 19, 3, 5, 2, 3이 부분(y 데이터)을 바꾸고 싶어 하실 거예요. 예시와 같이 고정 데이터면 상관없겠지만 때에 따라 바뀌어야 하는 데이터라면 flask로 생성한 변수를 그때그때 넣어줘야 하니까 json데이터로 넣어줘야 합니다.

def predictCoin():
    symbol = request.args.get('symbol')
    if symbol:
        symbol = symbol.upper()
    else:
        return redirect("/")
    ticker = f"KRW-{symbol}"
    preds_inversed = predict(ticker)
    y_preds = preds_inversed
    days = list(range(1, 31))
    return render_template('prediction.html', symbol=symbol, days=days, y_preds=y_preds)

일단 제가 만든 코드에서는 days가 x축 라벨이고 y_preds가 y 데이터에 속하는데요, 이것을 아래와 같이 prediction.html에서 labels: {{ days | to json }}, data: {{ y_preds | to json }}라고 적용시켜줍니다. 그냥 html에서 하는 것처럼 {{ days }}, {{ y_preds }}라고 하면 적용이 되지 않습니다.

<script>
        var ctx = document.getElementById("Chart").getContext("2d");
        var Chart = new Chart(ctx, {
          type: "line",
          data: {
            labels: {{ days | tojson }},
            datasets: [
              {
                label: "Expected {{symbol}} Price",
                data: {{ y_preds | tojson }},
                borderColor: "rgba(247, 16, 74, 1)",
                borderWidth: 1,
              },
            ],
          },
          options: {
            scales: {
              y: {
                beginAtZero: false,
              },
            },
          },
        });
      </script>

그런데 저는 여기서 다음과 같은 에러가 뜹니다

Object of type ndarray is not JSON serializable flask

왜냐하면 y_preds가 ndarray였기 때문입니다. list 타입이어야 하나 봅니다. 그래서 다음 링크를 참고하여  https://stackoverflow.com/questions/51685322/object-of-type-ndarray-is-not-json-serializable

 

Object of type 'ndarray' is not JSON serializable

I am new to python and machine learning. I have a Linear Regression model which is able to predict output based on the input which I have dumped to be used with a web service. See the code below: ...

stackoverflow.com

아래에서 세 번째 줄의 y_preds = preds_inversed 부분에 .to_list()를 추가하여 ndarray에서 리스트로 만들어주었습니다. (day는 이미 리스트 형식이므로 손 볼 필요가 없었습니다)

def predictCoin():
    symbol = request.args.get('symbol')
    if symbol:
        symbol = symbol.upper()
    else:
        return redirect("/")
    ticker = f"KRW-{symbol}"
    preds_inversed = predict(ticker)
    y_preds = preds_inversed.tolist()
    days = list(range(1, 31))
    return render_template('prediction.html', symbol=symbol, days=days, y_preds=y_preds)

이후 저는 모든 문제를 해결하고 다음과 같이 웹에 chart.js를 띄울 수 있었습니다.

 

참고할만한 사이트 : https://apt-info.github.io/%EA%B0%9C%EB%B0%9C/python-flask4-chart/

 

(python) flask 4. 코인 차트 그리기

이전 시간에 flask를 시작하는 방법과, get/post request를 처리하는 방법을 알아보았습니다.

apt-info.github.io