こんにちは、えびかずきです。
今回はMatplotlibのグラフをDjangoで使う方法について説明します!
最近Django開発にハマっている筆者ですが、Matplotlibでのグラフ描画に割とハマってしまったので、実装手順を備忘録として残しおきます。
こんな人におすすめ:
・DjangoのテンプレートにMatplotlibのグラフを表示させたい。
結論としては、views.pyでMatplotlibのグラフをsvg化してレスポンスを渡します。
では順を追って手順を見ていきましょう!
開発環境
OS:MacOS Catalina 10.15(ローカルサーバー)
IDE:PyCharm
Python:3.7.3
Django:2.2.2
Matplotlib:3.3.0
PostgreSQL:10.3
概要
今回の作業の流れは下図のとおりです。
グラフを表示させたいテンプレートにurlを埋め込んで、views.pyでグラフを描画する関数を定義してレスポンスを返します。
最終的には下のようにテンプレートによって出力されたページにMatplotlibのグラフを表示することが目標です。
テンプレートの編集(.html)
まずは、テンプレートを編集します。
グラフを埋め込みたい場所へ、<img>タグとしてグラフ埋め込んでおきます。
#テンプレート追記例
#diary_list.html
app_name = 'diary'
<img src="{% url 'diary:plot' %}" width=600 height=600>
ルーティングの設定(urls.py)
次にルーティングです。
urlリクエストをviews.pyへ受け渡すためのルーティングを設定してやります。
#urls.pyの追記例
app_name = 'diary' #アプリケーション名
urlpatterns = [
・
・
path('plot/', views.get_svg, name='plot')
]
ビューファイルの編集(views.py)
最後にビューファイルの編集です。
Matplotlibでグラフを描画してSVG化し、returnとしてHttpResponseを返します。
#views.py追記例
import matplotlib
#バックエンドを指定
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import io
from django.http import HttpResponse
#グラフ作成
def setPlt():
x = ["07/01", "07/02", "07/03", "07/04", "07/05", "07/06", "07/07"]
y = [3, 5, 0, 5, 6, 10, 2]
plt.bar(x, y, color='#00d5ff')
plt.title(r"$\bf{Running Trend -2020/07/07}$", color='#3407ba')
plt.xlabel("Date")
plt.ylabel("km")
# SVG化
def plt2svg():
buf = io.BytesIO()
plt.savefig(buf, format='svg', bbox_inches='tight')
s = buf.getvalue()
buf.close()
return s
# 実行するビュー関数
def get_svg(request):
setPlt()
svg = plt2svg() #SVG化
plt.cla() # グラフをリセット
response = HttpResponse(svg, content_type='image/svg+xml')
return response
これで、テンプレートにグラフが表示されるようになりました!
Matplotlibのエラー対策
Matplotlibはバックエンド指定しないとエラーが発生する場合があります。
筆者の環境では下のようなエラーが出ました。
UserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail.
plt.bar(x, y, color=’#00d5ff’)
Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘NSWindow drag regions should only be invalidated on the Main Thread!’
これに対しては、
下のようにバックエンドを『Agg』に指定してMatplotlibを実行することで解決することができました。
#views.py
import matplotlib
#バックエンドを指定
matplotlib.use('Agg')
import matplotlib.pyplot as plt
まとめ
今回は、MatplotlibのグラフをDjangoで使う方法について説明しました。
もしエラーに出くわしたら、Matplotlibのバックエンドを指定してみましょう。
参考サイト
今回の記事はこちらのサイトを参考にさせていただきました。
コメントを書く