Flask Matplotlib Python Webアプリケーション

【Python】Flaskを使ってWebアプリ上にMatplotlibプロットしたグラフを表示させる

この記事は約9分で読めます。

 

 

こんにちは、ミナピピン(@python_mllover)です!

 

今回はPythonのwebアプリ用フレームワークであるFlaskを使ってhtml上にMatplotlibで作成したグラフを表示させる方法について紹介したいと思います。

 

これまでの記事

FlaskによるWebアプリ開発①~簡単なWebページを表示させてみる

FlaskによるWebアプリ開発②~テンプレートエンジン(Jinja2)による動的Webページの生成

FlaskによるWebアプリ開発③~formタグでのデータのGET/POST送信

FlaskによるWebアプリ開発④~SQLAlchemyを使ってデータベースを操作する

 

webアプリケーション上でのグラフのプロット

 

webアプリケーションを作るうえで知っておきたいのがデータをプロットするテクニックですね。サイトに円グラフとかがあるとオシャレに見えます。

 

自分はReactやNode.jsは専門外なのでよく知りませんが、多分 JavaScript のライブラリでかっこいいグラフとかをひょいひょい作ってくれたりするのではないかなと思います。

 

ですが、Pythonでwebアプリーケーションを作るなら、やはりそのまま使い慣れた matplotlibで作ったグラフをwebアプリ上に表示させたいですよね。

 

そう思って今回はFlaskで作った簡単なhtml上にサーバー上でMatplotlibで作成したグラフを表示させる方法について色々模索したので、その結果を自分用に保存しておきます。

 

前提となるPythonの軽量Webアプリケーションフレームワークである「Flask」の使い方については以下の記事で解説しているのでそちらを参照してください。

 

 

 

 

FlaskとMatplotlibでwebアプリ上にプロットしたグラフを表示させる

 

サーバー上でMatplotlibを使って作ったグラフをhtmlで表示させる方法は大きく分けて2通りあります。

 

 

①生成した画像を画像データとしてレスポンスに返す

②内部ディレクトリにプロットした画像ファイル保存して、相対パスで呼び出す

 

 

画像ファイルを一時ファイルとして保存する方法はやってみたけどよく分からなかったというかpngをレスポンスにして返したら一発でできたので、また時間があるときに追記します。

 

画像データをレスポンスで返してhtml上にグラフを表示させたい場合は以下のように記述するとできます。インデントがおかしい場合はgitにコードを上げているのでそちらをダウンロードしてコピペしてください。

 

 

# ライブラリの読み込み
from flask import Flask, render_template, make_response, jsonify
from io import BytesIO
import urllib
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

# インスタンスの生成
app = Flask(__name__)

@app.route('/')
def index():
    return('<html><h1>実行結果</h1><p><p><img src="/graph1.png" ></img></html>')

@app.route('/graph1.png')
def graph1():
    # データからグラフをプロットする
    x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    y = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
    fig = plt.figure()
    ax = fig.add_subplot(111)
    plt.title('サンプル')
    plt.grid(which='both')
    plt.legend()
    plt.plot(x, y)
    # canvasにプロットした画像を出力
    canvas = FigureCanvasAgg(fig)
    png_output = BytesIO()
    canvas.print_png(png_output)
    data = png_output.getvalue()
    # HTML側に渡すレスポンスを生成する
    response = make_response(data)
    response.headers['Content-Type'] = 'image/png'
    response.headers['Content-Length'] = len(data)
    return response


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

参照:https://github.com/beginerSE/flask_plot_img/blob/master/app.py

 

<実行結果>

 

plt.grid()plt.legend() はplt.plotでグラフをプロットするときによく使う関数です。Matplotlibの基本については以下の記事で解説しています。

 

 

 

 

‘/graph1.png’というルーティングで行っているサーバ内部の処理の流れとしては以下のような感じです。

 

  1. グラフをプロットする
  2. データをBytesIOでバッファに書き込む
  3. バッファに書き込んだバイト文字列に置き換えた画像データをレスポンスとして返す

 

 

BytesIOとは、Pythonで作ったバイナリデータをPCのバッファという一時的な保管庫に格納できるようにする関数で、標準ライブラリの io に中に含まれています。バイナリデータとは主に画像や音声などのデータのことです。

 

今のPCだと画像や音声はペイントやWindowsメディアプレーヤーなんかで、音声や画像として自動で表示されますが、内部的にはコンピューターで扱うデータは全てバイナリデータなのです。

 

バイナリデータでも文字として認識できるテキストデータと違って、音声や画像は内部(バイナリ)と外部見え方が余りにも違うため、テキストデータと対比して用いられ、一般的にバイナリデータ=画像・音声のバイナリデータを指します。例えば画像データなんかをバイナリとして開くと↓みたいな感じです

 

 

引用元:https://java2005.cis.k.hosei.ac.jp/materials/lecture22/binstream.html

 

 

 

PythonだとStringIOというライブラリでバッファに書き込んでいた人もいたのですが、自分の環境ではStringIOなりライブラリがなくpipでも見つからなかったので、BytesIOを使いました。

 

あとで知ったのですが。thinkerとThinkerみたいにPython2と3で名前が変わり呼び出し方が変わっていたみたいです。

 

 

関連記事:【Python】Pandasのデータフレームをテーブルに高速INSERTする

 

 

後はこの画像データをresponse.headers['Content-Type']で、リクエストが来た際に画像データ(png)だと宣言しておき、レスポンスが返されるURL(/graph1.png)をindex.html上で<img src=’/graph1.png’></img>を使って埋め込むとFlaskで動かしているwebアプリ上にMatplotlibで作成したグラフを表示させることができます。

 

 

 <htmlに画像のURLを埋め込む場合の例>

<img src="https:/ドメイン//graph1.png" alt=""></img>

 

終わり

 

Pythonでやった機械学習の結果をグラフなりで見やすく返すみたいなFlaskで作る個人レベルの簡単webアプリならこの処理で行けると思います。

 

ただMatplotlibのグラフはあまりオシャレではないので、見栄えなどを重視するのであれば、javascriptのChartJSなんかを使う方が一般的だと思います。

 

 

関連記事:Chartjsとcolorschemesでオシャレなグラフをプロットする

 

 

今回のプロットに使ったx,yのデータをデータベースから引っ張ってくる処理に変えると仕組み的にはそれっぽくなりますね。PythonのFlaskならsqlite3という簡易データベースが標準で用意されているので、それと連携させるとミニデータベースサイトが作れます

 

 

関連記事:【Python】スクレイピングした価格データをデータベース(DB)に保存する

 

関連記事:【Python】Flask+SQLAlchemyを使って、「ひとこと掲示板」を作る

 

 

 

 


プログラミング・スクレイピングツール作成の相談を受け付けています!

クラウドワークス・ココナラ・MENTAなどでPython・SQL・GASなどのプログラミングに関する相談やツール作成などを承っております!

過去の案件事例:

  • Twitter・インスタグラムの自動化ツール作成
  • ウェブサイトのスクレイピングサポート
  • ダッシュボード・サイト作成
  • データエンジニア転職相談

これまでの案件例を見る

キャリア相談もお気軽に!文系学部卒からエンジニア・データサイエンティストへの転職経験をもとに、未経験者がどう進むべきかのアドバイスを提供します。


スポンサーリンク
/* プログラミング速報関連記事一覧表示 */
ミナピピンの研究室

コメント

  1. […] 関連記事:【Python】FlaskでMatplotlibでプロットしたグラフを表示させる […]

タイトルとURLをコピーしました