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

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

詳細はこちら
Flask

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

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Matplotlib

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

Python

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

Q&A

解決済

2回答

2468閲覧

Herokuにおいてmatplotlibで作成した画像が表示できない

mochmoch

総合スコア39

Flask

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

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Matplotlib

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

Python

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

0グッド

0クリップ

投稿2019/10/07 09:56

編集2019/10/07 10:09

問題点

flask,herokuの勉強でFlask入門を少し変えたものをherokuにデプロイしたのですが
フォームから入力されたものをmatplotlibでグラフ化し、保存したパスをデータベースに格納、格納されたパスを読み出しページを返すところでエラーが出ています。

エラー内容

2019-10-07T08:43:59.698002+00:00 app[web.1]: [2019-10-07 08:43:59,691] ERROR in app: Exception on /analysis [POST] 2019-10-07T08:43:59.698018+00:00 app[web.1]: Traceback (most recent call last): 2019-10-07T08:43:59.698021+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app 2019-10-07T08:43:59.698023+00:00 app[web.1]: response = self.full_dispatch_request() 2019-10-07T08:43:59.698025+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request 2019-10-07T08:43:59.698027+00:00 app[web.1]: rv = self.handle_user_exception(e) 2019-10-07T08:43:59.698029+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception 2019-10-07T08:43:59.69803+00:00 app[web.1]: reraise(exc_type, exc_value, tb) 2019-10-07T08:43:59.698032+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise 2019-10-07T08:43:59.698034+00:00 app[web.1]: raise value 2019-10-07T08:43:59.698036+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request 2019-10-07T08:43:59.698037+00:00 app[web.1]: rv = self.dispatch_request() 2019-10-07T08:43:59.698039+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request 2019-10-07T08:43:59.698041+00:00 app[web.1]: return self.view_functions[rule.endpoint](**req.view_args) 2019-10-07T08:43:59.698043+00:00 app[web.1]: File "/app/run.py", line 70, in analysis 2019-10-07T08:43:59.698045+00:00 app[web.1]: img = models.create_scatter(title, data, feature_class) 2019-10-07T08:43:59.698046+00:00 app[web.1]: File "/app/models.py", line 52, in create_scatter 2019-10-07T08:43:59.698048+00:00 app[web.1]: plt.savefig(save_path) 2019-10-07T08:43:59.69805+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/matplotlib/pyplot.py", line 722, in savefig 2019-10-07T08:43:59.698052+00:00 app[web.1]: res = fig.savefig(*args, **kwargs) 2019-10-07T08:43:59.698053+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/matplotlib/figure.py", line 2180, in savefig 2019-10-07T08:43:59.698055+00:00 app[web.1]: self.canvas.print_figure(fname, **kwargs) 2019-10-07T08:43:59.698057+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 2082, in print_figure 2019-10-07T08:43:59.698059+00:00 app[web.1]: **kwargs) 2019-10-07T08:43:59.69806+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py", line 527, in print_png

該当コード

python

1@app.route('/analysis', methods=['POST']) 2def analysis(): 3 """ 分析実行処理 """ 4 5 title = request.form['title'] 6 data = request.form['data'] 7 feature_class = request.form['class'] 8 9 img = models.create_scatter(title, data, feature_class) 10 11 con = get_db() 12 13 pk = models.insert(con, title, data, feature_class, img) 14 flash('登録処理が完了しました。') 15 return redirect(url_for('view', pk=pk))

python

1""" 2ビジネスロジックモジュール 3""" 4import json 5from matplotlib.font_manager import FontProperties 6import os 7import time 8import pandas as pd 9from pandas.plotting import scatter_matrix 10import matplotlib.pyplot as plt 11import matplotlib 12from flask import Flask 13 14app = Flask(__name__) 15 16matplotlib.use('Agg') 17 18font_path = "static/TakaoPGothic.ttf" 19font_prop = FontProperties(fname=font_path) 20 21 22def create_scatter(title, seq, feature_class): 23 24 VECTOR_DICT = {"a": [1, 1], "t": [-1, 1], "g": [-1, -1], "c": [1, -1]} 25 triplet = "" 26 BASE_PAIR = set(["a", "t", "g", "c"]) 27 x_coodinate = [0] 28 y_coodinate = [0] 29 30 with open("./static/self_information.json", "r") as jsonfile: 31 json_dict = json.load(jsonfile) 32 33 weight_dict = json_dict[feature_class] 34 35 for alphabet in seq.lower(): 36 if alphabet not in BASE_PAIR: 37 continue 38 triplet += alphabet 39 if len(triplet) < 3: 40 x_coodinate.append(x_coodinate[-1] + VECTOR_DICT[alphabet][0]) 41 y_coodinate.append(y_coodinate[-1] + VECTOR_DICT[alphabet][1]) 42 else: 43 triplet = triplet[-3:] 44 x_coodinate.append( 45 x_coodinate[-1] + VECTOR_DICT[alphabet][0] * weight_dict[triplet]) 46 47 y_coodinate.append( 48 y_coodinate[-1] + VECTOR_DICT[alphabet][1] * weight_dict[triplet]) 49 50 plt.title(title, fontproperties=font_prop) 51 plt.plot(x_coodinate, y_coodinate) 52 53 filename = time.strftime('%Y%m%d%H%M%S') + ".png" 54 save_path = os.path.join(app.root_path, "static", "result", filename) 55 url = "result/" + filename 56 plt.savefig(save_path) 57 plt.close() 58 59 return url

環境

Click==7.0
cycler==0.10.0
Flask==1.1.1
gunicorn==19.9.0
itsdangerous==1.1.0
Jinja2==2.10.1
kiwisolver==1.1.0
MarkupSafe==1.1.1
matplotlib==3.1.1
numpy==1.17.2
pandas==0.25.1
pyparsing==2.4.2
python-dateutil==2.8.0
pytz==2019.2
scipy==1.3.1
six==1.12.0
Werkzeug==0.16.0

やったこと

  • パスをapp.root_path基準とした
  • ローカルサーバでの確認python3 run.pyにて正常に動くことを確認

よろしくお願いします。

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

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

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

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

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

guest

回答2

0

Heroku の Dyno は、1日1回リブートされて、再デプロイされるので、リポジトリに保存されていない プログラムで作成されたファイルは、消えてなくなります。

ファイルが削除されるのをさけるには、ファイルの保存先に AWS S3 等の外部サービスを利用する必要があります。

公式ドキュメントの
Dynos and the Dyno Manager

Dynos are also restarted (cycled) at least once per day to help maintain the health of applications running on Heroku. Any changes to the local filesystem will be deleted.

(意訳) Dynosは1日に1回再起動されます。 ローカルファイルシステムへの変更はすべて削除されます。

と記載されています。

投稿2019/10/07 10:22

CHERRY

総合スコア25216

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

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

mochmoch

2019/10/08 08:57 編集

回答ありがとうございます [こちら](https://qiita.com/kiyokiyo_kzsby/items/f8aa0bf68007e18d6882)など24時間でデータベースが初期化される問題について把握していたのですが、データ保持は今回はあまり気にしていないのでsqlite3を使用していました。 エラーを見る限り、matplotlibの`savefig`がうまく行っていないのですがherokuではファイルへの書き出しがそもそもできないと考えるべきなのでしょうか?
guest

0

自己解決

githubにプロットしたファイルを入れておく空ディレクトリを追加していなかったのが問題かもしれません(heroku run bashでmkdirとかすればいいんだと思ってました)

gitで空ディレクトリを追加する方法は以下

bash

1touch <追加したい空ディレクトリ>/.gitkeep 2git add <追加したい空ディレクトリ>/.gitkeep 3git commit -m "add empty dir" 4git push heroku master

.gitkeepがいいのか.gitignoreがいいのかはよくわかりません

投稿2019/10/10 07:24

編集2019/10/10 07:25
mochmoch

総合スコア39

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問