開発者の皆さん、こんにちは!
Flaskを使うと簡単にWebアプリが作成できるようでしたので、Embedded Pythonを利用してIRISに保存した月毎の歩数データ(テーブル/グローバル)を matplotlibを利用してグラフ表示する簡単なWebアプリを作成してみました。
使っているPythonスクリプトファイルやHTMLは以下の通りです(図例はテーブルからデータを取る例ですが、サンプルにはグローバルからデータを取得する例も含まれます)。
サンプルはこちらに置いています👉https://github.com/Intersystems-jp/WalkSteps
IRISのインストール環境に合わせて、サンプルのディレクトリを分けています。
<Windows にIRISをインストールされている場合>
https://github.com/Intersystems-jp/WalkSteps/tree/master/Windows をご覧ください。
Windows上Pythonのバージョンは3.9で試しています。3.10では動作しませんでしたので、3.9でお試しください。
<Windows以外にIRISをインストールされている場合>
https://github.com/Intersystems-jp/WalkSteps/tree/master/Linux をご覧ください。
できあがりのイメージは以下の通りです。
1) 事前準備について
flaskとmatplitlib を pip でインストールします(Windows上にインストールしたIRISを使う場合もpipでインストールしてください)。
WindowsにインストールしたIRISを利用する場合のみ、以下ご確認ください。
テーブルからデータを取得する例を試される場合は table_goiris.py の2行目、グローバルからデータを取得する例を試される場合は、global_goiris.py の2行目に記載のある sys.path のディレクトリを変更します。
以下2つのディレクトリを確認し、sys.pathに追加してください。
- IRISインストールディレクトリ/mgr/python
- IRISインストールディレクトリ/lib/python
例:
sys.path+=['c:\\intersystems\\irishealth\\mgr\\python','c:\\intersystems\\irishealth\\lib\\python']
PythonPython
2)画面表示について
画面表示に使用しているHTMLは、index.html で、Flaskの render_template() 関数を利用し、HTTP応答としてHTML文書を返送しています。
(HTMLの継承ができたので、ベースとなるHTMLを base.htmlに作成し、index.htmlの中で {% extends 'base.html' %} と指定して base.html を継承しています)
{% extends 'base.html' %}
{% block body %}
<div class="form">
<form action="/" method='POST'>
<H2>{{selectmonth}}月の歩数</H2>
<div class="alert alert-warning" role="alert">
<label for="title"> 確認したい月を指定してください。</label>
<select name="selectmonth">
{% for month in monthlist %}
<option value="{{ month }}">{{ month }}月</option>
{% endfor %}
</select>
<input type="submit" value="歩数確認">
</div>
</form>
{% if rdate != "" %}
<div class="card-body">
{{ image | safe }}
</div>
{% endif %}
</div>
{% endblock %}
HTMLHTML
3)画面表示に使うグラフとデータについて
以下、Linux用ディレクトリ以下にあるコード例で解説しますが、Windowsディレクトリ以下にある内容と大枠に違いはありません。
3-1) テーブルデータを利用する場合
IRISからデータを取得する処理は、table_goiris.py に記述しています。
getMonthTbl()関数では、保存されている歩数データの「月」情報をSELECTで取得し、Pythonリストに格納し戻しています。
def getMonthTbl():
rs=iris.sql.exec("select DATEPART('MM',RecordDate) As month from MyHealth.Steps group by DATEPART('MM',RecordDate)")
monthlist=[]
for row in enumerate(rs):
monthlist.append(row[1][0])
return monthlist
PythonPython
createChartFromTbl()関数では、指定月の日付と歩数をSELECTで取得し、Pythonリストに格納し戻しています。
def createChartFromTbl(monthnumber):
sql="select tochar(RecordDate,'DD'),Steps from MyHealth.Steps WHERE DATEPART('MM',recorddate) = ?"
stmt=iris.sql.prepare(sql)
rs=stmt.execute(monthnumber)
rdate=[]
steps=[]
for row in enumerate(rs):
rdate.append(row[1][0])
steps.append(row[1][1])
return rdate,steps
PythonPython
table_goiris.py で作成したリストを利用して、table_app.pyの中でグラフを生成しています。
matplotlibで作成したグラフを、HTMLに埋め込む方法については、こちらのページ(https://shiren-blog.com/flask-matplotlib-graph-demo/)を参考にさせていただきました。
(imgタグのsrcにBase64でエンコードしたグラフのデータをセットし、index.htmlに当てはめる方法をとっています)
import base64
from io import BytesIO
import matplotlib.pyplot as plt
from flask import Flask, render_template, request
import table_goiris as goiris
app = Flask(__name__)
@app.route('/',methods=['GET','POST'])
def index():
#月取得(テーブル編)
monthlist=goiris.getMonthTbl()
if request.method=='GET':
defaultmonth=7
else:
result=request.form
defaultmonth=result['selectmonth']
#print(defaultmonth)
#データ取得(テーブル編)
result=goiris.createChartFromTbl(defaultmonth)
rdate=result[0]
steps=result[1]
#参考にしたページ:https://shiren-blog.com/flask-matplotlib-graph-demo/
#グラフ作成
fig = plt.figure(figsize=(10, 5))
ax = fig.add_subplot(111)
if defaultmonth=="5":
color="green"
elif defaultmonth=="6":
color="orange"
else:
color="blue"
ax.plot(rdate, steps, label="test",marker="o",color=color,linestyle="-.")
#バッファに保存
buf=BytesIO()
fig.savefig(buf,format='png')
#グラフをHTMLに埋め込むように変換
data=base64.b64encode(buf.getbuffer()).decode('ascii')
image_tag = f'<img src="data:image/png;base64,{data}"/>'
return render_template("index.html",image=image_tag,monthlist=monthlist,selectmonth=defaultmonth)
if __name__=="__main__":
#app.run(debug=True,host='0,0,0,0',port="8081")
app.run(debug=True,host='0.0.0.0')
PythonPython
3-2) グローバルを利用する場合
IRISからデータを取得する処理は、global_goiris.py に記述しています。
getMonthGlo()関数では、保存されている歩数データの「月」情報を取得し、Pythonリストに格納し戻しています(ObjectScriptで$Order()してるのと同じイメージで記述できます)。
def getMonthGlo():
glo=iris.gref("^MySteps")
monthlist=[]
month=""
while True:
month=glo.order([2022,month])
if (month==None):
break
monthlist.append(month)
return monthlist
PythonPython
createChartFromGlo()関数では、指定月の日付と歩数を得し、Pythonリストに格納し戻しています(ObjectScriptで$Order()してるのと同じイメージで記述できます)。
def createChartFromGlo(monthnumber):
glo=iris.gref("^MySteps")
rdate=[]
steps=[]
date=""
while True:
date=glo.order([2022,monthnumber,date])
if (date==None):
break
rdate.append(date)
steps.append(glo[2022,monthnumber,date])
return rdate,steps
PythonPython
global_goiris.py で作成したリストを利用して、global_app.pyの中でグラフを生成しています。
matplotlibで作成したグラフを、HTMLに埋め込む方法については、こちらのページ(https://shiren-blog.com/flask-matplotlib-graph-demo/)を参考にさせていただきました。
(imgタグのsrcにBase64でエンコードしたグラフのデータをセットし、index.htmlに当てはめる方法をとっています)
import base64
from io import BytesIO
import matplotlib.pyplot as plt
from flask import Flask, render_template, request
import global_goiris as goiris
app = Flask(__name__)
@app.route('/',methods=['GET','POST'])
def index():
#月取得(グローバル編)
monthlist=goiris.getMonthGlo()
if request.method=='GET':
defaultmonth=7
else:
result=request.form
defaultmonth=result['selectmonth']
#print(defaultmonth)
#データ取得(グローバル編)
result=goiris.createChartFromGlo(defaultmonth)
rdate=result[0]
steps=result[1]
#参考にしたページ:https://shiren-blog.com/flask-matplotlib-graph-demo/
#グラフ作成
fig = plt.figure(figsize=(10, 5))
ax = fig.add_subplot(111)
if defaultmonth=="5":
color="green"
elif defaultmonth=="6":
color="orange"
else:
color="blue"
ax.plot(rdate, steps, label="test",marker="o",color=color,linestyle="-.")
#バッファに保存
buf=BytesIO()
fig.savefig(buf,format='png')
#グラフをHTMLに埋め込むように変換
data=base64.b64encode(buf.getbuffer()).decode('ascii')
image_tag = f'<img src="data:image/png;base64,{data}"/>'
return render_template("index.html",image=image_tag,monthlist=monthlist,selectmonth=defaultmonth)
if __name__=="__main__":
#app.run(debug=True,host='0,0,0,0',port="8081")
app.run(debug=True,host='0.0.0.0')
PythonPython
4)サンプルデータの作成
サンプルデータの作成に利用するMyHealth.StepクラスをIRISのUSERネームスペースにインポートします。
- スタジオを利用されている場合は、USERネームスペースに接続先を変更した後、*.cls をスタジオにドラッグ&ドロップするとインポートできます。
- VSCodeを利用されている場合は、使用するIRISのUSERネームスペースに接続した後、MyHealth.Step.clsをワークスペースで開き、保存します(保存と同時にコンパイルが実行されます)。
- 管理ポータルからインポートする場合は、管理ポータル > システムエクスプローラ > クラス (USERネームスペース選択) の画面で「インポート」ボタンからインポートできます。
続いて、IRISにログインし(またはターミナルを開き)USERネームスペースに接続していることを確認し、以下実行します。
テーブルを利用する場合:
do ##class(MyHealth.Steps).create()
グローバルを利用する場合:
do ##class(MyHealth.Steps).createGlobal()
※2022年5月1日~7月31日の歩数データがランダムに作成されます(実行毎に再作成するようにしています)。
5)実行!
5-1)Windows以外で試す場合
IRISインストールディレクトリ/bin/irispythonコマンドを利用して table_app.py または global_app.py を実行します。
impor irisを行うため、irispythonを利用しています。
IRISインストールディレクトリが、 /usr/irissys である場合の例は以下の通りです(実行環境に合わせてディレクトリはご変更ください)。
※実行する table_app.py または global_app.py もフルパスで指定しています。
テーブル編
/usr/irissys/bin/irispython /home/isjedu/WalkSteps/Linux/table_app.py
グローバル編
/usr/irissys/bin/irispython /home/isjedu/WalkSteps/Linux/global_app.py
5-2)Windowsで試す場合
実行前の準備が完了しているかご確認ください(リンク先の「3.実行前の確認」をご確認ください)。
Pythonコマンドの後に、table_app.py または global_app.py をフルパスで指定してください。
テーブル編
python c:\WorkSpace\WalkSteps\Windows\table_app.py
グローバル編
python c:\WorkSpace\WalkSteps\Windows\global_app.py
いかがでしたでしょうか。FlaskもPythonもとても便利ですね!🐍
もっと良い方法をご存知の方いらっしゃいましたら、ぜひ共有いただけると嬉しいです!
コミュニティへの投稿、お待ちしております_(._.)_
👇Embedded Python概要やEmbedded Pythonでデータベースプログラミング(SQLアクセス編)を解説するYouTubeプレイリストとサンプルコード一式公開中です!👇
【はじめてのInterSystems IRIS】Embedded Python セルフラーニングビデオシリーズ公開!