Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

Flask matplotlibを使ってグラフを表示する方法(JavaScriptのChart.jsを使ってグラフを描画)

はじめに

今回はちょっと寄り道してFlaskでグラフを表示してみます。本当はグラフのアニメーションを作りたかったのですが諦めました。あとで調べたところ、JavaScriptを使ったほうが簡単できれいに出来るみたいだったのでそちらも作成してみました。

 

動作環境

Windows10
Python 3.7.5
Flask 1.1.1

 

コード

test.py

from flask import Flask, render_template, make_response
from io import BytesIO
import urllib
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

import random
import numpy as np


app = Flask(__name__)

fig = plt.figure()
ax = fig.add_subplot()

x = [1, 2, 3, 4, 5, 6]
y = [0, 1, 2, 3, 4, 5]


@app.route('/')
def index():
    plt.cla()

    rand = random.randint(0, 5)
    y[rand] += 1

    plt.title('sample')
    plt.bar(x, y)
    plt.legend()

    canvas = FigureCanvasAgg(fig)
    png_output = BytesIO()
    canvas.print_png(png_output)
    data = png_output.getvalue()

    response = make_response(data)
    response.headers['Content-Type'] = 'image/png'
    response.headers['Content-Length'] = len(data)

    return response


if __name__ == "__main__":
    app.run()

 

解説

こちらを参考にさせていただきました。こちらで詳しい解説はされています。

tkstock.site

簡単に説明すると、「plt」グラフを作成(描画はしていません)して「canvas」に画像を出力します。その画像データ「data」をレスポンス「response」で生成します。

png_output = BytesIO()

「BytesIO()」を使用すると普通はファイルに書き出す操作を省き仮想的にメモリ上に書き出すことができます。

data = png_output.getvalue()

バッファの全内容を含むバイト列を返します。

 

うーん、わかったようなわからないような(わかってない)。「グラフの画像データをメモリ上にバイト型データで渡して、また引っ張ってきて画像データに戻す」感じでしょうか。画像データをそのまま渡せたらいいのにと思ってしまいます。

 

f:id:Start_python:20200126185906p:plain

とりあえずグラフを表示できました。

 

rand = random.randint(0, 5)
y[rand] += 1

この2行が入っているのでページを更新(再表示)するとグラフの値が変化します。

plt.cla()

この1行が入らないと再表示するたびにグラフの色が変わっておもしろいです。

 

JavaScriptのChart.jsを使ってグラフを表示

次にhtmlで直接グラフを表示してみます。こちらがコードです。

test.html

<div class="chart-container" style="position: relative; width: 100%; height: 100%;">
  <canvas id="myChart"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js">
</script>
<script>
    var ctx = document.getElementById("myChart").getContext('2d');
    var myBarChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ['1', '2', '6', '4', '5', '6'],
            datasets: [{
                label: 'sample',
                data: [0, 1, 2, 3, 4, 5],
                backgroundColor: "rgba(0,0,255,0.8)"
            }]
        }
    });
</script>

結果はこちらです。

f:id:Start_python:20200126190703p:plain

 

JavaScriptはまったく勉強していないので解説できません。JavaScriptでのグラフの書き方は、検索するといくらでも出てくると思いますので今回は省略させていただきます。
(<html><head><body><script>についてもまったくわからないので勉強します)

 

まとめ

今回はグラフを動かすことは出来なかったですが、表示の方法はなんとなくわかりました。ずっとPythonだけをしてきたのでmatplotlibを使った方法がしっくりきますが、JavaScriptで表示するほうが簡単な気もします。

Flaskを覚えるにはJavaScriptを知らないと難しそうです。Pythonは少し休憩してJavaScriptの勉強をはじめてみたくなりました。

 

 

↓よかったらポチッとしていってください。

にほんブログ村 IT技術ブログ Pythonへ
にほんブログ村