水温のグラフ出力
https://scrapbox.io/files/61224573d97c800021442c44.jpg
Raspberry Piによる水温の自動計測で得られた水温データをグラフ出力して可視化する 上のグラフがここでの完成形 ハチャメチャかっこいい
あしゅりー.iconはコレをかっこいいと思っています
あしゅりーアクアリウムでは学術的で理想的な正しくお行儀の良いグラフの書き方を徹底的に無視し、あしゅりー.iconがイケてると思うスタイリッシュな見た目にこだわった
前提条件
このページは水温の自動計測にて定期的な水温データ計測が出来ている環境を想定する システム構成図
「Water temp sensor」にて水温計測システムを既に実現している場合が対象
システム構成図.icon
要件
計測した水温を時間ごとのグラフで出力できる
水温グラフを定期的に自動更新できる
仕様
仕様1:水温の数値データリストを入力すると、過去12時間の水温変移のグラフが画像データで出力される
仕様2:定期的にグラフ画像の再生成が行われ、最新の水温データで更新される
必要なもの
以下のように時刻と水温のセットを想定する
code:temperature.log
2021-08-22 20:50:00,27.437
2021-08-22 21:00:00,27.682
2021-08-22 21:10:00,28.146
2021-08-22 21:20:00,28.315
設計
matplotlibでグラフを生成する
matplotlibの基本的な内容は他所参照のこと
matplotlibのインストール
Numpyも一緒にインストールしておく
code:Terminal
$ pip install matplotlib
$ pip install numpy
以下のコードを実施した際、上手く動かない場合はmatplotlibのバージョンが古い可能性がある
適宜アップデートのこと
やること
上記のtemperature.logを読み込む(入力)
読み込んだデータを元にグラフを生成
グラフを画像データ(背景透過)として一旦出力
別途用意した背景画像の上に上記のグラフ画像を合成
やった
こんなん
code:output_graph.py
import numpy as np
import matplotlib as mpl
from matplotlib.dates import DateFormatter
import matplotlib.pyplot as plt
mpl.use('Agg')
from PIL import Image
def graph():
fig = plt.figure()
ax = fig.add_subplot(111)
# temperature.logの読み込み(入力).
data_x, data_y = np.loadtxt(
fname = '/home/asyley/temperature.log',
delimiter = ',',
dtype = 'unicode',
unpack = True,
)
data_x = data_x.astype(np.datetime64)
data_y = data_y.astype(np.float64)
# 読み込んだデータを元にグラフを生成.
color1 = 'yellow'
ax.set_xlabel('Time',color=color1)
ax.set_ylabel('Water temperature °C',color=color1) ax.spines'left'.set(color=color1) ax.spines'top'.set(color=color1) ax.xaxis.set_major_formatter(DateFormatter('%H:%M'))
# 読み込んだ水温データの最終行(直近の時刻)から過去12時間をX軸とする.
ax.set_xlim(data_x-1 - (60*60*12), data_x-1) ax.set_ylim(26.0,28.5)
ax.tick_params(length=0, colors=color1, labelsize=8)
ax.grid(color=color1, linestyle='dotted', linewidth=0.5)
ax.plot(data_x,data_y,color=color1)
# グラフを画像データ(背景透過)として一旦出力.
fig.savefig('/home/asyley/graph_only.png', transparent=True, dpi=300)
# 別途用意した背景画像の上に上記のグラフ画像を合成.
im1 = Image.open('/home/asyley/graph_only.png')
im2 = Image.open('/home/asyley/background.jpg').resize(im1.size)
im2.paste(im1,(0,0),im1)
im2.save('/home/asyley/output.png')
if __name__ == '__main__':
graph()
以下を実行して水温のグラフを出力する
code:Terminal
$ python3 output_graph.py
上記graph_only.pngには、以下のような背景が透過されたグラフ画像が出力される
https://scrapbox.io/files/617d35415cd8d0001d56fc65.png
まぶしい
background.jpgには背景画像として使いたいものを事前に用意しておく
今回は以下の画像を用意した(モノクロの方が見やすいのでトップ画像から変更した)
https://scrapbox.io/files/617d368e32c63e001da47318.jpg
事前にガウスノイズのぼかし加工とかしておくと後で合成するグラフが見やすくなる
上記2つの画像データが合成され、output.pngに以下のような画像が出力される
https://scrapbox.io/files/617d381eafa122001d644c2c.png
完了 ⇒ 仕様1:水温の数値データリストを入力すると、過去12時間の水温変移のグラフが画像データで出力される
グラフの定期更新
定期的(10分おき等)に水温計測し、temperature.logにデータが蓄積されていれば、グラフも定期的に自動で更新(生成)する
crontabで上記プログラムを定期的に実行する
水温の自動計測にて、毎時0分、10分、20分、30分、40分、50分にて10分おきに自動計測している場合を想定 crontabにて以下を既に設定しているはず
code:crontab
*/10 * * * * /usr/bin/python3 /home/asyley/get_temperature.py
get_temperature.pyの実行により新しい水温データが計測されたタイミングで上記のoutput_graph.pyも実行されるように変更を加える
完了 ⇒ 仕様2:定期的にグラフ画像の再生成が行われ、最新の水温データで更新される
活用
任意のタイミングで最新のグラフを覗けるようにすれば実用的
現在の様子
魔改造しすぎて手が付けられんようになった
https://scrapbox.io/files/6154892cc45d0c001f9c0e75.jpg