🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

5171閲覧

matplotlibで得たグラフを画像として保存し、flaskへ表示したい

tatsu0117

総合スコア11

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/01/28 09:40

matplotlibで得たグラフを画像として保存し、flaskへ表示したいと考えています。
プログラムは完全に独学の素人ですので、文章の書き方はご容赦頂けますと幸いです。
webアプリケーションはherokuを用いてgitへアップしています。

python

1--グラフ化するプログラム 2plt.savefig("statics\images\temp.png") 3↑内部ディレクトリに保存?できているのか不明 4return render_template(・・・

html側にて

html

1<p><img src="statics\images\temp.png" alt="keepaglaf"></p>

この方法ではディレクトリが存在せず表示がうまくいきませんでした。
responseを用いて行う方法もあるとのことでしたがそちらの方法もやり方が悪く動作しませんでした。

お力添えいただけますと大変助かります。
ご回答いただくのに必要な情報が足りてない場合は、ご指摘いただけますと幸いです。
どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2021/01/28 10:36

一度ファイルに保存するのは必須ですか?それとも動的に生成したグラフを HTML 上に表示できればよいですか?
tatsu0117

2021/01/28 10:38

早速レスポンス頂きありがとうございます。 保存は必須ではなく動的にグラフをHTML上に表示出来れば大丈夫です!
guest

回答2

0

ベストアンサー

matplotlib の Figure を画像化して base64 文字列に変換し、インライン画像 として、テンプレート上に img タグで表示すればいいと思います。

templates/index.html

<img src="data:image/png;base64,{{ img }}" />

main.py

python

1import base64 2from io import BytesIO 3 4import numpy as np 5import matplotlib 6 7matplotlib.use("Agg") 8from matplotlib import pyplot as plt 9from flask import Flask, render_template 10 11app = Flask(__name__) 12 13 14def fig_to_base64_img(fig): 15 """画像を base64 に変換する。 16 """ 17 # png 形式で出力する。 18 io = BytesIO() 19 fig.savefig(io, format="png") 20 # base64 形式に変換する。 21 io.seek(0) 22 base64_img = base64.b64encode(io.read()).decode() 23 24 return base64_img 25 26 27def create_graph(): 28 """matplotlib のグラフを作成する。 29 """ 30 x = np.linspace(-10, 10, 100) 31 y = x ** 2 32 33 fig, ax = plt.subplots() 34 ax.plot(x, y) 35 ax.set_title("Title", c="darkred", size="large") 36 37 return fig 38 39 40@app.route("/") 41def hello(): 42 # グラフを作成する。 43 fig = create_graph() 44 # グラフを画像化して、base64 形式にエンコードする。 45 img = fig_to_base64_img(fig) 46 47 return render_template("index.html", img=img) 48 49 50if __name__ == "__main__": 51 app.run(debug=True)

Github に動作するコード全体を載せましたので、なにか疑問点があったらコメントしてください。

イメージ説明

投稿2021/01/28 10:46

編集2021/01/28 10:47
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatsu0117

2021/01/28 13:28

tiitoi様 ご教示いただいた方法でやってみたところ一発でできました! ご回答いただきありがとうございます! 早急にご回答いただき大変助かりました。
guest

0

「responseを用いて行う」というのは、以下のような事でしょうか。
(numpyとかmatplotlibとかは知らないので、tiitoiさんのプログラムから、拝借します)

python

1# coding: utf-8 2 3import io, urllib.parse 4from flask import Flask, make_response, Response, abort, request 5import numpy as np 6from matplotlib import pyplot as plt 7 8app = Flask(__name__) 9 10@app.route('/') 11def index(): 12 start = -10 13 stop = 10 14 num = 100 15 return '''<!DOCTYPE html> 16<html> 17<body> 18<p>Hello, world!</p> 19<img src="./graph" /> 20</body> 21</html> 22''' 23 24@app.route('/graph') 25def graph(): 26 start, stop, num = -10, 10, 100 27 # 「<img src="./graph?start=%2d10&stop=10&num=100" />」というように、 28 # パラメータを渡して指定する事も可。 29 #try: 30 # start = int(request.args.get('start')) 31 # stop = int(request.args.get('stop')) 32 # num = int(request.args.get('num')) 33 #except: 34 # abort(404) 35 x = np.linspace(start, stop, num) 36 y = x ** 2 37 38 fig, ax = plt.subplots() 39 ax.plot(x, y) 40 ax.set_title('Title', c='darkred', size='large') 41 with io.BytesIO() as f: 42 fig.savefig(f, format='png') 43 data = f.getvalue() 44 45 return make_response(Response(data, mimetype='image/png')) 46 47if __name__ == '__main__': 48 app.run(debug=True) 49 50

投稿2021/01/28 12:54

katsuko

総合スコア3536

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatsu0117

2021/01/28 13:30

katsuko様 ご回答いただきありがとうございます。 tiitoiさんの回答で解決しましたが、ご教示いただいた方法も参考にさせていただきたいと思います! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問