2021-02-23 05:09:26 +00:00
|
|
|
""" makes the nice plots """
|
|
|
|
|
2021-02-23 07:36:29 +00:00
|
|
|
from datetime import datetime, timedelta
|
2021-02-23 05:09:26 +00:00
|
|
|
|
|
|
|
from matplotlib import pyplot as plt
|
|
|
|
import numpy as np
|
|
|
|
import pandas as pd
|
|
|
|
import psycopg2
|
|
|
|
|
|
|
|
from app.db_connect import db_connect, db_close
|
|
|
|
|
|
|
|
|
|
|
|
def create_current(config):
|
|
|
|
""" recreate current graph """
|
|
|
|
# last three hours
|
|
|
|
now = datetime.now()
|
|
|
|
now_human = now.strftime('%c')
|
|
|
|
now_epoch = int(now.strftime('%s'))
|
|
|
|
last_3h = now_epoch - 3 * 60 * 60
|
|
|
|
last_3h_limit = int(60 * 3)
|
|
|
|
# connect
|
|
|
|
conn, cur = db_connect(config)
|
|
|
|
# get data
|
|
|
|
cur.execute(
|
2021-02-23 07:36:29 +00:00
|
|
|
f'SELECT epoch_time, aqi_value FROM aqi \
|
|
|
|
WHERE epoch_time > {last_3h} ORDER BY epoch_time DESC \
|
|
|
|
LIMIT {last_3h_limit};')
|
2021-02-23 05:09:26 +00:00
|
|
|
rows = cur.fetchall()
|
|
|
|
# close db
|
|
|
|
db_close(conn, cur)
|
2021-02-23 07:36:29 +00:00
|
|
|
# set title
|
|
|
|
time_from = datetime.fromtimestamp(rows[-1][0]).strftime('%H:%M')
|
|
|
|
time_until = datetime.fromtimestamp(rows[0][0]).strftime('%H:%M')
|
2021-03-07 05:05:43 +00:00
|
|
|
plt_title = f'AQI values last 3h: {time_from} - {time_until}'
|
2021-02-23 05:09:26 +00:00
|
|
|
# parse rows
|
2021-02-23 07:36:29 +00:00
|
|
|
sample_rate = '3min'
|
2021-02-27 08:10:23 +00:00
|
|
|
x, y = build_plt(rows, sample_rate, '%H:%M')
|
2021-02-23 05:09:26 +00:00
|
|
|
# calc x_ticks
|
|
|
|
x_ticks = []
|
|
|
|
for num, i in enumerate(x):
|
|
|
|
minute = int(i.split(':')[1])
|
|
|
|
if minute % 15 == 0:
|
|
|
|
x_ticks.append(num)
|
|
|
|
# write plt
|
2021-02-23 07:36:29 +00:00
|
|
|
file_name = 'current'
|
|
|
|
write_plt(x, y, plt_title, x_ticks, file_name)
|
2021-02-23 05:09:26 +00:00
|
|
|
message = f'recreated current graph: {now_human}'
|
|
|
|
print(message)
|
|
|
|
|
|
|
|
|
2021-02-24 04:52:25 +00:00
|
|
|
def rebuild_3days(config):
|
|
|
|
""" wrapper to recreate all three days of graphs """
|
|
|
|
now = datetime.now()
|
|
|
|
# get axis
|
|
|
|
x_1, y_1, plt_title_1, x_ticks_1 = get_axis(1, now, config)
|
|
|
|
x_2, y_2, plt_title_2, x_ticks_2 = get_axis(2, now, config)
|
|
|
|
x_3, y_3, plt_title_3, x_ticks_3 = get_axis(3, now, config)
|
|
|
|
# set max
|
|
|
|
y_max = max(y_1.append(y_2).append(y_3)) + 50
|
|
|
|
# write plot
|
|
|
|
write_plt(x_1, y_1, plt_title_1, x_ticks_1, 'day-1', y_max)
|
|
|
|
write_plt(x_2, y_2, plt_title_2, x_ticks_2, 'day-2', y_max)
|
|
|
|
write_plt(x_3, y_3, plt_title_3, x_ticks_3, 'day-3', y_max)
|
|
|
|
print('recreaded last three days plt')
|
|
|
|
|
|
|
|
|
|
|
|
def get_axis(day, now, config):
|
|
|
|
""" recreate plot for single days """
|
|
|
|
day_delta = now.date() - timedelta(days = day)
|
|
|
|
day_from = int(day_delta.strftime('%s'))
|
|
|
|
day_until = int(day_delta.strftime('%s')) + 60 * 60 * 24
|
|
|
|
# make the SELECT
|
|
|
|
conn, cur = db_connect(config)
|
|
|
|
cur.execute(
|
|
|
|
f'SELECT epoch_time, aqi_value FROM aqi \
|
|
|
|
WHERE epoch_time > {day_from} \
|
|
|
|
AND epoch_time < {day_until} \
|
|
|
|
ORDER BY epoch_time DESC LIMIT 720;'
|
|
|
|
)
|
|
|
|
rows = cur.fetchall()
|
|
|
|
db_close(conn, cur)
|
|
|
|
# title
|
|
|
|
time_stamp = day_delta.strftime('%Y-%m-%d')
|
|
|
|
plt_title = f'AQI values from: {time_stamp}'
|
|
|
|
# build plt
|
|
|
|
x_ticks = np.arange(0, 97, step=8)
|
|
|
|
sample_rate = '15min'
|
2021-02-27 08:10:23 +00:00
|
|
|
x, y = build_plt(rows, sample_rate, '%H:%M')
|
2021-02-24 04:52:25 +00:00
|
|
|
return x, y, plt_title, x_ticks
|
|
|
|
|
|
|
|
|
2021-02-27 08:10:23 +00:00
|
|
|
def rebuild_7days(config):
|
|
|
|
""" recreate last-7 days from db """
|
|
|
|
# setup
|
|
|
|
now = datetime.now()
|
|
|
|
day_until = int(now.date().strftime('%s'))
|
|
|
|
day_from = day_until - 7 * 24 * 60 * 60
|
|
|
|
# get data
|
|
|
|
conn, cur = db_connect(config)
|
|
|
|
cur.execute(
|
|
|
|
f'SELECT epoch_time, aqi_value FROM aqi \
|
|
|
|
WHERE epoch_time > {day_from} \
|
|
|
|
AND epoch_time < {day_until} \
|
|
|
|
ORDER BY epoch_time DESC LIMIT 30 * 24 * 7;'
|
|
|
|
)
|
|
|
|
rows = cur.fetchall()
|
|
|
|
db_close(conn, cur)
|
|
|
|
# title
|
|
|
|
date_from = datetime.fromtimestamp(rows[-1][0]).strftime('%Y-%m-%d')
|
|
|
|
date_until = datetime.fromtimestamp(rows[0][0]).strftime('%Y-%m-%d')
|
|
|
|
plt_title = f'AQI values from: {date_from} until {date_until}'
|
2021-03-05 07:29:56 +00:00
|
|
|
# build axis of plot
|
|
|
|
x, y_1, y_2 = build_last7_plt(rows)
|
2021-02-27 08:10:23 +00:00
|
|
|
# make ticks
|
|
|
|
x_range = np.arange(0, 84, step=12)
|
|
|
|
x_date_time = pd.to_datetime(x).dt.date.unique()
|
|
|
|
x_dates = np.asarray([i.strftime('%Y-%m-%d') for i in x_date_time])
|
|
|
|
x_ticks = x_range, x_dates
|
|
|
|
# write the plot
|
2021-03-05 07:29:56 +00:00
|
|
|
write_last7_plt(x, y_1, y_2, x_ticks, plt_title)
|
2021-02-27 08:10:23 +00:00
|
|
|
print('recreaded last-7 days graph')
|
|
|
|
|
|
|
|
|
|
|
|
def build_plt(rows, sample_rate, time_format):
|
2021-02-23 05:09:26 +00:00
|
|
|
""" parse rows returns axis"""
|
|
|
|
# build x y
|
|
|
|
x_timeline = [datetime.fromtimestamp(i[0]) for i in rows]
|
|
|
|
y_aqi_values = [int(i[1]) for i in rows]
|
|
|
|
# build dataframe
|
|
|
|
data = {'timestamp': x_timeline, 'aqi': y_aqi_values}
|
|
|
|
df = pd.DataFrame(data)
|
|
|
|
# reindex as timeseries
|
|
|
|
indexed = df.set_index('timestamp')
|
|
|
|
indexed.sort_values(by=['timestamp'], inplace=True)
|
2021-02-23 07:36:29 +00:00
|
|
|
mean = indexed.resample(sample_rate).mean()
|
2021-02-23 05:09:26 +00:00
|
|
|
mean.reset_index(level=0, inplace=True)
|
2021-02-27 08:10:23 +00:00
|
|
|
mean['timestamp'] = mean['timestamp'].dt.strftime(time_format)
|
2021-02-23 05:09:26 +00:00
|
|
|
mean['aqi'] = mean['aqi'].round()
|
|
|
|
# set axis
|
|
|
|
x = mean['timestamp']
|
|
|
|
y = mean['aqi']
|
2021-02-23 07:36:29 +00:00
|
|
|
return x, y
|
2021-02-23 05:09:26 +00:00
|
|
|
|
|
|
|
|
2021-03-05 07:29:56 +00:00
|
|
|
def build_last7_plt(rows):
|
|
|
|
""" build axis for last7 plot """
|
|
|
|
sample_rate = '2h'
|
|
|
|
# build x y
|
|
|
|
x_timeline = [datetime.fromtimestamp(i[0]) for i in rows]
|
|
|
|
y_aqi_values = [int(i[1]) for i in rows]
|
|
|
|
# build dataframe
|
|
|
|
data = {'timestamp': x_timeline, 'aqi': y_aqi_values}
|
|
|
|
df = pd.DataFrame(data)
|
|
|
|
indexed = df.set_index('timestamp')
|
|
|
|
indexed.sort_values(by=['timestamp'], inplace=True)
|
|
|
|
mean = indexed.resample(sample_rate).mean()
|
|
|
|
mean['avg'] = mean['aqi'].resample('1d').mean()
|
|
|
|
mean['avg'] = mean.avg.shift(6)
|
|
|
|
|
|
|
|
mean['avg'][0] = (mean['avg'].iloc[6] + mean['aqi'][0]) / 2
|
|
|
|
mean['avg'][-1] = (mean['avg'].iloc[-6] + mean['aqi'][-1]) / 2
|
|
|
|
|
|
|
|
mean['avg'].interpolate(method='polynomial', order=3, inplace=True)
|
|
|
|
mean.reset_index(level=0, inplace=True)
|
|
|
|
mean['timestamp'] = mean['timestamp'].dt.strftime('%Y-%m-%d %H:%M')
|
|
|
|
mean['aqi'] = mean['aqi'].round()
|
|
|
|
mean['avg'] = mean['avg'].round()
|
|
|
|
x = mean['timestamp']
|
|
|
|
y_1 = mean['aqi']
|
|
|
|
y_2 = mean['avg']
|
|
|
|
return x, y_1, y_2
|
|
|
|
|
|
|
|
|
2021-02-24 04:52:25 +00:00
|
|
|
def write_plt(x, y, plt_title, x_ticks, file_name, y_max=''):
|
2021-02-23 05:09:26 +00:00
|
|
|
""" save plot to file """
|
|
|
|
# calc ticks
|
2021-02-24 04:52:25 +00:00
|
|
|
if not y_max:
|
|
|
|
y_max = np.ceil(y.max()/50)*50 + 50
|
2021-02-23 05:09:26 +00:00
|
|
|
# setup plot
|
|
|
|
plt.style.use('seaborn')
|
|
|
|
plt.plot(x, y, color='#313131',)
|
|
|
|
plt.fill_between(x, y, y2=0, where=(y > 0), color='#85a762', interpolate=True) # good
|
|
|
|
plt.fill_between(x, y, y2=50, where=(y > 50), color='#d4b93c', interpolate=True) # moderate
|
|
|
|
plt.fill_between(x, y, y2=100, where=(y > 100), color='#e96843', interpolate=True) # ufsg
|
|
|
|
plt.fill_between(x, y, y2=150, where=(y > 150), color='#d03f3b', interpolate=True) # unhealthy
|
|
|
|
plt.fill_between(x, y, y2=200, where=(y > 200), color='#be4173', interpolate=True) # vunhealthy
|
|
|
|
plt.fill_between(x, y, y2=300, where=(y > 300), color='#714261', interpolate=True) # hazardous
|
|
|
|
plt.fill_between(x, y, y2=0, where=(y > 0), color='#ffffff', alpha=0.1, interpolate=True) # soft
|
2021-02-27 08:10:23 +00:00
|
|
|
# handle passing ticks and lables separatly
|
|
|
|
if len(x_ticks) == 2:
|
|
|
|
plt.xticks(x_ticks[0], x_ticks[1])
|
|
|
|
else:
|
|
|
|
plt.xticks(x_ticks)
|
2021-02-23 05:09:26 +00:00
|
|
|
plt.yticks(np.arange(0, y_max, step=50))
|
2021-03-07 05:05:43 +00:00
|
|
|
plt.title(plt_title, fontsize=20)
|
2021-02-23 05:09:26 +00:00
|
|
|
plt.tight_layout()
|
2021-02-23 07:36:29 +00:00
|
|
|
plt.savefig(f'dyn/{file_name}.png', dpi = 300)
|
2021-02-23 05:09:26 +00:00
|
|
|
plt.figure()
|
2021-03-05 07:29:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def write_last7_plt(x, y_1, y_2, x_ticks, plt_title):
|
|
|
|
""" plot last-7 only """
|
|
|
|
y_max = np.ceil(max(y_1.append(y_2))/50)*50 + 50
|
|
|
|
# plot
|
|
|
|
plt.style.use('seaborn')
|
|
|
|
plt.plot(x, y_1, color='#313131', label='2hour avg')
|
|
|
|
plt.plot(x, y_2, color='#cc0000', label='daily avg')
|
|
|
|
plt.fill_between(x, y_1, y2=0, where=(y_1 > 0), color='#85a762', interpolate=True) # good
|
|
|
|
plt.fill_between(x, y_1, y2=50, where=(y_1 > 50), color='#d4b93c', interpolate=True) # moderate
|
|
|
|
plt.fill_between(x, y_1, y2=100, where=(y_1 > 100), color='#e96843', interpolate=True) # ufsg
|
|
|
|
plt.fill_between(x, y_1, y2=150, where=(y_1 > 150), color='#d03f3b', interpolate=True) # unhealthy
|
|
|
|
plt.fill_between(x, y_1, y2=200, where=(y_1 > 200), color='#be4173', interpolate=True) # vunhealthy
|
|
|
|
plt.fill_between(x, y_1, y2=300, where=(y_1 > 300), color='#714261', interpolate=True) # hazardous
|
|
|
|
plt.fill_between(x, y_1, y2=0, where=(y_1 > 0), color='#ffffff', alpha=0.1, interpolate=True) # soft
|
|
|
|
plt.xticks(x_ticks[0], x_ticks[1])
|
|
|
|
plt.yticks(np.arange(0, y_max, step=50))
|
2021-03-07 05:05:43 +00:00
|
|
|
plt.title(plt_title, fontsize=20)
|
2021-03-05 07:29:56 +00:00
|
|
|
plt.legend()
|
|
|
|
plt.tight_layout()
|
|
|
|
plt.savefig('dyn/last-7.png', dpi = 300)
|
|
|
|
plt.figure()
|