GrovePi+の温湿度センサーから得たCSVファイルをmatplotlibでグラフ化(その2)
途中で、くじけちゃうかもと予告していたのですが、思いの外早く達成することが出来ました。先人たちの、Webページに帰するところ大です。
まず、どんなWebページを参考にしたかといいますと「或る阿呆の記>matplotlibでx軸の時刻情報をフォーマットする」から着想を得て「質問をすることでしか得られない、回答やアドバイスがある。>Python, matplotlib で時間軸(HH:MM:SS)にする方法」で試行を繰り返し、今まで作ったものを変更しました。なぜ、「matplotlibでx軸の時刻情報をフォーマットする」だけでは上手くゆかなかったのかはPandasライブラリをファイルの読み込みで使っていたからです。Pandasは当方のRasppberry Pi2には導入しておらず。CSVファイルへの書き込みはCSVライブラリを、python3への読み込みはNamPyライブラリでも出来ていましたので、このためだけに導入するのも何かおっくうだったからです。これが、「その3」でCSVファイルらかのグラフ化に影響をおよぼすとは思いもよならなかったのですが、それはまた「その3」で語ることになるかと思います。結局、私の環境の中で公開されているソースコードで最初に動いたのが「Python, matplotlib で時間軸(HH:MM:SS)にする方法」だったのです。
次に、実際の内容解説ですが、やっぱり説明が難しいので最後はソースコードを読み解いてもらうしかないのです。
第1に、時間をtからttに変え、ttは[0]~[120]と2時間図示できるようにし、日付型になるように現在時刻をまず代入しました。
第2にtt.pop(120)と古い値を1つずつ順番がずれるようにしました。さらに、あいたtt[0]にtt.insert(0,dt)と現在の値が入るようにしました。ここは、tt[0]=dtでも同じことになります。それから、確認用のprint()文を、通し番号が1列目に出てくるように微修正を加えたり、CSVファイルの時刻の記入をtt[0]にしました。
第3にグラフの作成部分ですX軸、Y軸更新p1,=host.plot()内のtをttに変更しました。同じくp1,=par1.plot()、p2,=par2.plot()もttに変更しました。更に、横軸(X軸)の範囲指定はhost.set_xlim([tt[0] - datetime.timedelta(hours=2), tt[0]])に変更し時間が経つ毎に書き換える様にしました。これでグラフは描けるようになります。ここまで来るのに結構、試行錯誤が必要でした。
第4にグラフの体裁です。「matplotlibでx軸の時刻情報をフォーマットする」を参考にhost.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d\n%H:%M'))をhost = plt.subplot()の後に記入しました。これで、グラフの横軸(X軸)に日時が2行で表示され、時間が経過する毎(1分毎)に更新されます。そして、グラフの下及び右の余白を調整してhost = plt.subplot()の前にplt.subplots_adjust(bottom=0.15,right=0.75)記入しました。重複しているグラフ下地を削除しました。
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pygame
from pygame.locals import *
import sys
import time
import datetime
#from datetime import datetime as dt
import grovepi#GrovePiを使うときに必要
import math
import csv
from time import sleep #ループを1分ごとに動作させるためsleep()を使うため必要
from matplotlib.font_manager import FontProperties#日本語化に必要
#Grove Temperature & Humidity Sensor ProをGrovePiのD4ポートにつなぐ
#このファイルで the White colored sensorを使うため以下を設定
#ケーブル線はSIG,NC,VCC,GND
sensor = 4 # デジタルポート4に設定(後でgrovepiで変数を渡す)
#温湿度センサーの型(タイプ)
#センサーの色
blue = 0 # The Blue(青) colored sensor.
white = 1 # The White(白) colored sensor.
font_path = '/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf'#日本語化
font_prop = FontProperties(fname=font_path)
plt.rcParams['font.family'] = font_prop.get_name()
def main():
temps = [0.0]*121 # 気温格納
humis = [0.0]*121 # 湿度格納
zyoukis = [0.0]*121 # 水蒸気量格納
tt = [datetime.datetime.now()]*121# 横軸(とりあえず現在の時刻を入れている)
number=0 # 通し番号を整数値0から始めるよう定義
pygame.init() # Pygameを初期化
screen = pygame.display.set_mode((300, 100)) # 画面作成(横300×100)
pygame.display.set_caption("温湿度") # タイトルバー
font = pygame.font.Font(None, 50) # 文字の設定
#CSVファイル最上部標題行入力
with open('temp02.csv','w',encoding='utf-8')as f:#ファイルオープン'W'は上書きモード。
writer=csv.writer(f, lineterminator='\n')
writer.writerow(['番号','日時','気温(℃)','湿度(%)','水蒸気量(g/m3)'])
while True:
dt = datetime.datetime.now()# 現在の時刻をdtに代入
if str(dt.second) == "0":
screen.fill((0,0,0)) # 画面のクリア
temp,humi = grovepi.dht(sensor,white)# grovepi内のdht関数にポート番号と型番号を渡し気温、湿度を受け取る
temp = str(temp) # 気温を文字列にする
humi = str(humi) # 湿度を文字列にする
text = font.render(temp + "[℃]" + humi +"[%]", False, (255,255,255)) # 表示する文字の設定
screen.blit(text, (10, 10)) # レンダ,表示位置
pygame.display.flip() # 画面を更新して、変更を反映
# 温度データのリスト更新
temps.pop(120)
humis.pop(120)
zyoukis.pop(120)
tt.pop(120)
temps.insert(0,float(temp)) # 文字列にしたデータ(温度)を少数を含む数値に変換
humis.insert(0,float(humi)) # 文字列にしたデータを(湿度)少数を含む数値に変換
zyoukis.insert(0,(0.794*(humis[0]/100*6.1078*pow(10,(7.5*temps[0])/(temps[0]+237.3))))/(1 +0.00366*temps[0])) # 気温及び相対湿度より空気1立米当たり水蒸気量に変換
tt.insert(0,dt)#記録日時をtt[0]へ代入
print("%i "% (number)+dt.strftime("%Y-%m-%d %H:%M:%S.%f")+" temp = %.1f C humi = %.1f %% zyouki = %.2f g/m^3" % (temps[0],humis[0],zyoukis[0]))
# センサーがエラーになってもグラフを補間するためエラーの場合、前の数字を代入
if str(temps[0])=='nan' and str(humis[0])=='nan':
temps[0]=temps[1]
humis[0]=humis[1]
zyoukis[0]=zyoukis[1]
#データをCSV化
with open('temp02.csv','a',encoding='utf-8')as f:#ファイルオープン'a'は追記モード
writer=csv.writer(f, lineterminator='\n')#末尾は改行としている
writer.writerow([number,tt[0],str(temps[0]),str(humis[0]),str(zyoukis[0])])#データ書き込み
# グラフ表示設定
plt.subplots_adjust(bottom=0.15,right=0.75)#グラフ下及び右の余白調整
host = plt.subplot()
host.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d\n%H:%M')) #X軸の月日時の表示
par1 = host.twinx()
par2 = host.twinx()
par2.spines["right"].set_position(("axes", 1.2))#右に3番めY軸目盛を作成
p1, = host.plot(tt, temps, 'r-',label="気温[℃]") # X軸、Y軸更新
p1.set_ydata(temps)
p2, = par1.plot(tt, humis, 'b-',label="湿度[%]") # X軸、Y軸更新
p2.set_ydata(humis)
p3, = par2.plot(tt, zyoukis, 'g-',label="水蒸気量[$g/m^3$]") #X軸、Y軸更新
p3.set_ydata(zyoukis)
host.set_xlim([tt[0] - datetime.timedelta(hours=2), tt[0]])#X軸の範囲指定
host.set_ylim(10, 25)#Y1軸の範囲指定
par1.set_ylim(0, 100)#Y2軸の範囲指定
par2.set_ylim(0, 25)#Y3軸の範囲指定
plt.title("Real-time 気温 湿度、水蒸気量[$g/m^3$]")
host.set_xlabel("日時")
host.set_ylabel("気温 [℃]")
par1.set_ylabel("湿度[%]")
par2.set_ylabel("水蒸気量[$g/m^3$]")
tkw = dict(size=4, width=1.5)#目盛の大きさと太さ
host.yaxis.label.set_color(p1.get_color())#Y1軸ラベルの文字色
par1.yaxis.label.set_color(p2.get_color())#Y2軸ラベルの文字色
par2.yaxis.label.set_color(p3.get_color())#Y3軸ラベルの文字色
lines = [p1, p2, p3]
host.legend(lines, [l.get_label() for l in lines])#凡例
plt.grid()#グラフ補助線の記載
plt.pause(.01)#グラフをFigure1に記載(プロット)
plt.clf()#表示窓をクリアにする
for event in pygame.event.get():
# ウィンドウを閉じるボタンが押されたら終了処理
if event.type == QUIT:
pygame.quit()
plt.close()
f.close()
sys.exit()
number=number+1 # 次の通し番号の作成
sleep(1)
sleep(0.1)
if __name__ == '__main__':
main()





最近のコメント