WebページにおけるJavaScriptモジュールでの描画は、モニタでの閲覧には便利だが、キャプチャした図は印刷物にするには品質が悪すぎる。
同じデータを、印刷に適したスケーラブル画像をpythonで描画する。
印刷用ファイルを作るときは、plt.show()の前にファイルへの出力を書く。(スケーラブル画像svgが好ましい。)
クラススクリプトは一番下にある。最初にこれを実行しておく。
points = ["kofu25", "kofu26", "kofu27"]
plotHourlyData(points, "20190925", "a")
points = ["kofu25", "kofu26", "kofu27"]
plotDailyData(points, "20190825", "20190924","a")
points = ["kofu25", "kofu26", "kofu27"]
plotDailyData(points, "20190825", "20190924","g")
points = ["ff02", "ff03", "ff04"]
plotDailyData(points, "20190825", "20190924","a", "ff")
# 参考
# 地点IDと名前
import pandas as pd
filename = {"kofu": "/var/www/html/kofu/kofu_position.csv",
"fuefuki": "/var/www/html/ff/sensor_points.csv",
"hakushu": "/home/toyoki/public_html/hakushu/points_hakushu.csv",
"ttri": "/home/toyotamngr/csv/toyota/sensor_points.csv"}
df = pd.read_csv(filename['kofu'])
df
# 処理全体のクラススクリプト
json_root = "https://8tops.yamanashi.ac.jp/"
import json
import requests
import pandas as pd
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.family'] = 'IPAPGothic' # 全体のフォントを設定
def plotHourlyData(points, day, addr='a', area='kofu', dev="all"):
resp = requests.get(json_root + area +"/"
+ "getHourlyCounts.php"
+ "?sdate=" + day
+ "&edate=" + day
+ "&addr=" + addr)
json_dict = resp.json()
plot_data = {}
# プロットするデータをDataFrameに: 数値に変換する必要があることに注意
pointAttrib = getPointAttribute(area)
for pt in points:
if not pt in json_dict.keys():
continue
plot_data[pointAttrib[pt]['短縮名']] = list(
map(float, json_dict[pt][day]['hourly']))
df4plot = pd.DataFrame(plot_data)
# プロット
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(1, 1, 1)
ax = df4plot.plot(ax=ax, fontsize=12)
# 凡例は外側に固定
ax.legend(fontsize=12, loc='center left',
bbox_to_anchor=(1.05, 0.5), borderaxespad=0)
ax.set_title("地点アドレス数 (" + day + ")",
fontsize=12)
ax.set_xlabel("時間", fontsize=12)
ax.set_ylabel("アドレス数", fontsize=12)
plt.show()
def plotDailyData(points, sday, eday, addr='a', area='kofu'):
"""
指定したエリア内のpointsのデータを作図
points: 地点の単純なリスト
"""
resp = requests.get(json_root + area + "/"
+ "getHourlyCounts.php"
+ "?sdate=" + sday
+ "&edate=" + eday
+ "&addr=" + addr)
json_dict = resp.json()
plot_data = {}
pointAttrib = getPointAttribute(area)
for pt in json_dict:
if not pt in points:
continue
plot_data[pointAttrib[pt]['短縮名']] = {}
for day in json_dict[pt]:
day_by_datetime = datetime.strptime(day, "%Y%m%d")
plot_data[pointAttrib[pt]['短縮名']][day_by_datetime] = 0
for h in json_dict[pt][day]['hourly']:
plot_data[pointAttrib[pt]['短縮名']][day_by_datetime] += int(h)
df4plot = pd.DataFrame(plot_data)
# プロット
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(1, 1, 1)
ax = df4plot.plot(ax=ax, fontsize=12)
# 凡例は外側に固定
ax.legend(fontsize=12, loc='center left',
bbox_to_anchor=(1.05, 0.5), borderaxespad=0)
ax.set_title("地点アドレス数 (" + sday + "〜" + eday + ")",
fontsize=12)
ax.set_xlabel("日", fontsize=12)
ax.set_ylabel("アドレス数", fontsize=12)
plt.show()
def plotDailyDataByGroup(points, sday, eday, addr='a', area='kofu', dev="all"):
"""
何枚もの図を並べて書きたい場合にも対応
points: [{group_name: グループ名, points: [point1, point2, ...]}, ...]
"""
resp = requests.get(json_root + area + "/"
+ "getHourlyCounts.php"
+ "?sdate=" + sday
+ "&edate=" + eday
+ "&addr=" + addr
+ "&dev=" + dev) # devはWi-Fiデバイスを表すがkofuでは効力がない
json_dict = resp.json()
plot_data = {}
pointAttrib = getPointAttribute(area)
fig_col = 2
fig_row = int(len(points) / fig_col + 1)
fig = plt.figure(figsize=(8*fig_col, 5*fig_row))
# 余白を設定
plt.subplots_adjust(wspace=0.6, hspace=0.3)
fig_num = 0
for group in points:
plot_data = {}
for pt in group['points']:
if not pt in json_dict:
continue
plot_data[pointAttrib[pt]['短縮名']] = {}
for day in json_dict[pt]:
day_by_datetime = datetime.strptime(day, "%Y%m%d")
plot_data[pointAttrib[pt]['短縮名']][day_by_datetime] = 0
for h in json_dict[pt][day]['hourly']:
plot_data[pointAttrib[pt]['短縮名']][day_by_datetime] += int(h)
df4plot = pd.DataFrame(plot_data)
df4plot.replace(0, np.nan, inplace=True)
# print(df4plot)
# プロット
fig_num +=1
sub_fig = fig.add_subplot(fig_row, fig_col, fig_num)
ax = df4plot.plot(ax=sub_fig, fontsize=10)
# 凡例は外側に固定
ax.legend(fontsize=12, loc='center left',
bbox_to_anchor=(1.05, 0.5), borderaxespad=0)
ax.set_title(group['group_name'] + " (" + sday + "〜" + eday + ")",
fontsize=12)
# ax.set_xlabel("日", fontsize=12)
ax.set_ylabel("アドレス数", fontsize=12)
plt.show()
def getPointAttribute(area):
filename = {"kofu": "/var/www/html/kofu/kofu_position.csv",
"ff": "/var/www/html/ff/sensor_points.csv",
"hakushu": "/home/toyoki/public_html/hakushu/points_hakushu.csv",
"ttri": "/home/toyotamngr/csv/toyota/sensor_points.csv"}
df = pd.read_csv(filename[area])
return df.set_index('センサ名').T.to_dict()
# 1か月のデータをカテゴリごとに描画
df1 = pd.read_csv(filename['kofu']).groupby("カテゴリ")
group = []
group.append({"group_name": "中央", "points": df1.get_group("中央")['センサ名'].tolist()})
group.append({"group_name": "丸の内", "points": df1.get_group("丸の内")['センサ名'].tolist()})
group.append({"group_name": "北口・朝日町", "points": df1.get_group("北口・朝日町")['センサ名'].tolist()})
group.append({"group_name": "甲府駅周辺", "points": df1.get_group("甲府駅周辺")['センサ名'].tolist()})
plotDailyDataByGroup(group, "20190801", "20190831","a")
df1 = pd.read_csv(filename['fuefuki']).groupby("グループ")
group = []
group.append({"group_name": "上部", "points": df1.get_group("上部")['センサ名'].tolist()})
group.append({"group_name": "下部", "points": df1.get_group("下部")['センサ名'].tolist()})
plotDailyDataByGroup(group, "20190801", "20190831",addr="a", area="ff", dev="all")