Skip to content

Commit

Permalink
Plots design work, added optional trend to plots, added wind speed an…
Browse files Browse the repository at this point in the history
…d direction as parameters.
  • Loading branch information
meteoadriatic committed Nov 16, 2018
1 parent 7860732 commit 5b37da0
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 34 deletions.
88 changes: 66 additions & 22 deletions app.py
Expand Up @@ -8,6 +8,7 @@
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
import numpy as np
import params

app = Flask(__name__)

Expand Down Expand Up @@ -59,8 +60,9 @@ def statistics():
sel_param = ''
sel_loc = ''
stats = ''
trendline = False
table_truncated = False
show_plot=False
show_plot = False
form = StatisticsForm()
cur = mysql.connection.cursor()

Expand All @@ -82,6 +84,11 @@ def statistics():
''')
parameters = cur.fetchall()
parameters = [i[0] for i in parameters]

# Append calculated parameters (params.py)
appends = ['wspd_10', 'wdir_10']
parameters = parameters + appends

form.parameters.choices = parameters


Expand All @@ -91,41 +98,77 @@ def statistics():
sel_param = form.parameters.data
sel_startdate = form.startdate.data
sel_enddate = form.enddate.data

trendline = form.trendline.data

if sel_param == 'wspd_10':
df = params.wspd_10(cur, sel_loc, sel_startdate, sel_enddate)
sql_response = tuple(zip(df.index, df['wspd_10']))
elif sel_param == 'wdir_10':
df = params.wdir_10(cur, sel_loc, sel_startdate, sel_enddate)
sql_response = tuple(zip(df.index, df['wdir_10']))
else:
# Retrieve data from MySQL
SQL = ''' SELECT datetime, {}
FROM model_output
WHERE location=%s
AND datetime > %s
AND datetime <= %s
ORDER BY datetime
'''.format(sel_param)
cur.execute(SQL, (sel_loc, sel_startdate, sel_enddate))
sql_response = cur.fetchall()

# Load MySQL response into pandas dataframe
df = pd.DataFrame(list(sql_response))
df = df.set_index([0])
df.index.name = ''
df.columns = [sel_param]
SQL = ''' SELECT datetime, {}
FROM model_output
WHERE location=%s
AND datetime > %s
AND datetime <= %s
ORDER BY datetime
'''.format(sel_param)
cur.execute(SQL, (sel_loc, sel_startdate, sel_enddate))
sql_response = cur.fetchall()

# Load MySQL response into pandas dataframe
df = pd.DataFrame(list(sql_response))
df.set_index([0], inplace=True)
df.index.name = ''
df.columns = [sel_param]

# Build statistics list from df.describe() output
statskeys=df.describe().index.tolist()
statsvalues=df.describe().values.tolist()
statskeys = df.describe().index.tolist()
statsvalues = df.describe().values.tolist()
statsvalues = [item for sublist in statsvalues for item in sublist]
statsvalues = ['%.1f' % elem for elem in statsvalues]
stats = [list(a) for a in zip(statskeys, statsvalues)]

# Create a plot from datetime (x axis) and chosen parameter (y axis)
# Create a plot from datetime (x axis) and selected parameter (y axis)
fig, ax = plt.subplots()
fig.set_size_inches(12.5, 5.0)
fig.tight_layout()
fig.autofmt_xdate()
ax.set_axisbelow(True)
ax.grid(linestyle='--', linewidth='0.5', color='#41B3C5', alpha=0.8, axis='both')
ax.plot(df.index, df[sel_param])
ax.grid(linestyle='--', linewidth='0.4', color='#41B3C5', alpha=0.8, axis='both')

# Customize plot according to selected parameter
if sel_param == 'precave' or sel_param == 'precpct':
ax.bar(df.index, df[sel_param], alpha=0.15)
ax.set_ylim(bottom=0)
elif sel_param == 'rdrmax':
ax.bar(df.index, df[sel_param], alpha=0.3, color='red', width=0.2)
ax.set_ylim(bottom=0)
elif 'wdir_' in sel_param or 'VVEL' in sel_param:
scatsiz=max((100000/(len(df.index))),50)
ax.scatter(df.index, df[sel_param], s=scatsiz, alpha=0.1)
elif 'SWRF' in sel_param or 'LWRF' in sel_param\
or 'RH_' in sel_param or 'CAPE' in sel_param\
or 'CIN' in sel_param or 'PWAT' in sel_param or 'CLD' in sel_param:
ax.plot(df.index, df[sel_param])
ax.fill_between(df.index, 0, df[sel_param], color='#41B3C5', alpha=0.3)
ax.set_ylim(bottom=0)
else:
ax.plot(df.index, df[sel_param])

# Include linear trendline
if trendline == True:
x = mdates.date2num(df.index)
y = df[sel_param]
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
ax.plot(df.index, p(x), color='red')
plt.title("TREND SLOPE=%.6fx" % (z[0]))

# Make x-axis ticks evenly spaced - auto spacing doesn't look nice on matplotib v3
plt.xlim(sel_startdate, sel_enddate)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
ax.xaxis.set_major_locator(ticker.AutoLocator())

Expand All @@ -150,6 +193,7 @@ def statistics():
stats=stats,
sel_param=sel_param,
sel_loc=sel_loc,
trendline=trendline,
plot='/static/images/plot.png',
show_plot=show_plot,
table_truncated=table_truncated)
Expand Down
7 changes: 3 additions & 4 deletions forms.py
@@ -1,6 +1,5 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField, DateField
from flask import request
from wtforms import StringField, SubmitField, SelectField, DateField, BooleanField
from datetime import datetime

class SQLForm(FlaskForm):
Expand All @@ -12,5 +11,5 @@ class StatisticsForm(FlaskForm):
parameters = SelectField('parameters')
startdate = DateField('startdate', format='%Y-%m-%d', default=datetime(2018, 9, 1, 00, 00, 00, 00))
enddate = DateField('enddate', format='%Y-%m-%d', default=datetime(2018, 9, 30, 00, 00, 00, 00))
submit = SubmitField('Pošalji')

trendline = BooleanField('trendline')
submit = SubmitField('Pošalji')
46 changes: 46 additions & 0 deletions params.py
@@ -0,0 +1,46 @@
import pandas as pd
import numpy as np

# from vulkan:
# df.loc[(df['wspd'].isnull()), 'wspd'] = (df['u10'] ** 2 + df['v10'] ** 2) ** 0.5
# df.loc[(df['wd'].isnull()), 'wd'] = 57.3 * np.arctan2(df['u10'], df['v10']) + 180

def wspd_10(cur, sel_loc, sel_startdate, sel_enddate):
SQL = ''' SELECT datetime, UGRD_10, VGRD_10
FROM model_output
WHERE location=%s
AND datetime > %s
AND datetime <= %s
ORDER BY datetime
'''
cur.execute(SQL, (sel_loc, sel_startdate, sel_enddate))
sql_response = cur.fetchall()

df = pd.DataFrame(list(sql_response))
df.set_index([0], inplace=True)
df['wspd_10'] = np.nan
df.loc[(df['wspd_10'].isnull()), 'wspd_10'] = ((df[1] ** 2 + df[2] ** 2) ** 0.5).astype(int)
df = df[['wspd_10']]
df.index.name = ''

return df

def wdir_10(cur, sel_loc, sel_startdate, sel_enddate):
SQL = ''' SELECT datetime, UGRD_10, VGRD_10
FROM model_output
WHERE location=%s
AND datetime > %s
AND datetime <= %s
ORDER BY datetime
'''
cur.execute(SQL, (sel_loc, sel_startdate, sel_enddate))
sql_response = cur.fetchall()

df = pd.DataFrame(list(sql_response))
df.set_index([0], inplace=True)
df['wdir_10'] = np.nan
df.loc[(df['wdir_10'].isnull()), 'wdir_10'] = (57.3 * np.arctan2(df[1], df[2]) + 180).astype(int)
df = df[['wdir_10']]
df.index.name = ''

return df
20 changes: 12 additions & 8 deletions templates/statistics.html
Expand Up @@ -6,7 +6,7 @@

<form method="POST">
<fieldset class="form-group">
<legend class="border-bottom mb-2">Odaberi lokaciju</legend>
<legend class="border-bottom mb-1">Odaberi lokaciju</legend>
<div class="form-group">
<select name="locations">
{% for location in locations %}
Expand All @@ -20,7 +20,7 @@
</div>
</fieldset>
<fieldset class="form-group">
<legend class="border-bottom mb-2">Odaberi parametar</legend>
<legend class="border-bottom mb-1">Odaberi parametar</legend>
<div class="form-group">
<select name="parameters">
{% for parameter in parameters %}
Expand All @@ -34,16 +34,20 @@
</div>
</fieldset>
<fieldset class="form-group">
<legend class="border-bottom mb-2">Odaberi početni i završni datum</legend>
<legend class="border-bottom mb-1">Odaberi početni i završni datum</legend>
<div class="row">
<div class="col-md-auto">
{{ form.startdate(class="form-control form-control-lg") }}
{{ form.startdate(class="form-control") }}
<small id="firststartdate" class="form-text text-muted">Najraniji dostupni datum: 2018-08-01</small>
</div>
<div class="col-md-auto">
{{ form.enddate(class="form-control form-control-lg") }}
{{ form.enddate(class="form-control") }}
<small id="laststartdate" class="form-text text-muted">Najkasniji dostupni datum: 2018-10-31</small>
</div>
<div class="col-md-auto">
{{ form.trendline(class="form-control") }}
<small id="trendline" class="form-text text-muted">Dodaj trend na graf</small>
</div>
</div>
</fieldset>
<div class="form-group">
Expand All @@ -52,7 +56,7 @@

{% if show_plot==True %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Statistika</legend>
<legend class="border-bottom mb-2">Statistika</legend>
<div class="container">
<table class="table table-striped table-hover table-sm">
<tbody>
Expand All @@ -71,13 +75,13 @@
</div>
</fieldset>
<fieldset class="form-group">
<legend class="border-bottom mb-4">Graf</legend>
<legend class="border-bottom mb-2">Graf</legend>
<div class="container">
<img class="img-fluid" src="{{plot}}" alt="Plot">
</div>
</fieldset>
<fieldset class="form-group">
<legend class="border-bottom mb-4">Podaci</legend>
<legend class="border-bottom mb-2">Podaci</legend>
{% if table_truncated == True %}
<div class="alert alert-warning" role="alert">Tablica je ograničena na najviše 30 dana.</div>
{% endif %}
Expand Down

0 comments on commit 5b37da0

Please sign in to comment.