from datetime import date, datetime, timedelta
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
import pandas as pd
import plotly.graph_objects as go
import streamlit as st
from plotly.subplots import make_subplots
def hour_rounder(t):
if int(t.minute)>= 30:
time_1 = str(int(t.hour)+1)
if len(time_1) == 1:
return "0"+time_1+":00"
else:
return str(time_1)+":00"
else:
if len(str(t.hour)) == 1:
return "0"+str(t.hour)+":00"
else:
return str(t.hour)+":00"
def peak_hours(t):
peak = ['07:00', "08:00", '09:00', "17:00", "18:00", "19:00"]
if t in peak:
return 1
else:
return 0
def weekend(w):
end = ['Saturday', 'Sunday']
if w in end:
return 1
else:
return 0
def vehicle_cat(v):
if v >= 0 and v < 2:
return 0
elif v >= 2 and v < 4:
return 1
elif v >= 4 and v < 6:
return 2
elif v >= 6 and v < 8:
return 3
else:
return 4
def data_split(final_table):
X = final_table.loc[:,['day', 'hour','view']]
Y = final_table.loc[:,'cat']
X = pd.get_dummies(X)
X.loc[:,['peak', 'weekend']] = final_table.loc[:,['peak', 'weekend']]
x_train, x_test, y_train, y_test = train_test_split(X, Y, train_size=0.7,
test_size=0.3,
shuffle=True, random_state=13)
return x_train, x_test, y_train, y_test
def convert_date(date):
return datetime.strptime(date, "%Y-%m-%d").strftime('%A')
def create_row(x_train, date_d, hour, view):
if date_d is None:
date_d = "2023-04-11"
if hour is None:
hour = "09:00"
if view is None:
view = "Johor-Tuas"
features = x_train.columns
d_dict = {}
day = datetime.strptime(date_d, "%Y-%m-%d").strftime('%A')
hour = str(hour)
view = str(view)
col_day = "day_" + day
col_hour = 'hour_'+ hour
col_view = 'view_'+view
for i in features:
if i == col_day or i == col_hour or i == col_view:
d_dict[i] = [1]
else:
d_dict[i] = [0]
end = ['Saturday', 'Sunday']
peak = ['07:00', "08:00", '09:00', "17:00", "18:00", "19:00"]
if day in end:
d_dict['weekend'] = 1
if hour in peak:
d_dict['peak'] = 1
result = pd.DataFrame.from_dict(d_dict, orient='columns')
for i in features:
result[i] = result[i].astype('category')
return result
def prep_data_pred_plot(df):
df = df.sort_values(by=['date']).reset_index(drop=True)
df['date'] = pd.to_datetime(df['date'], format = "%Y-%m-%d")
df['day'] = df['date'].dt.day_name()
df.drop(columns=['motorcycle'], axis=1, inplace=True)
df['vehicle'] = df['car'] + df['large_vehicle']
transfer = {"View_from_Second_Link_at_Tuas_to_sg": 'Johor-Tuas',
"View_from_Second_Link_at_Tuas_to_jh": 'Tuas-Johor',
"View_from_Tuas_Checkpoint_to_sg": 'Johor-Tuas',
"View_from_Tuas_Checkpoint_to_jh": 'Tuas-Johor',
"View_from_Woodlands_Causeway_Towards_Johor_to_sg": 'Johor-Woodlands',
"View_from_Woodlands_Causeway_Towards_Johor_to_jh": 'Woodlands-Johor',
"View_from_Woodlands_Checkpoint_Towards_BKE_to_sg": 'Johor-Woodlands',
"View_from_Woodlands_Checkpoint_Towards_BKE_to_jh": 'Woodlands-Johor'}
new_table = df.replace({'view':transfer})
options = ['Johor-Woodlands','Woodlands-Johor','Johor-Tuas','Tuas-Johor']
final_df = new_table[new_table['view'].isin(options)]
final_df.loc[:, 'time'] = pd.to_datetime(final_df.loc[:,'time'], format='%H:%M:%S')
final_df.loc[:,'hour'] = final_df.loc[:,'time'].apply(hour_rounder)
final_table = final_df.groupby(['view', 'day', 'hour']).mean().reset_index().loc[:,['day', 'hour','view', 'vehicle']]
final_table['vehicle'] = final_table['vehicle'].apply(lambda x: round(x))
final_table.loc[:,'peak'] = final_table.loc[:,'hour'].apply(peak_hours)
final_table.loc[:,'peak'] = final_table.loc[:,'peak'].astype('category')
final_table.loc[:,'weekend'] = final_table.loc[:,'day'].apply(weekend)
final_table.loc[:,'weekend'] = final_table.loc[:,'weekend'].astype('category')
final_table.loc[:,'cat'] = final_table.loc[:,'vehicle'].apply(vehicle_cat)
final_table.loc[:,'cat'] = final_table.loc[:,'cat'].astype('category')
return final_table
def gen_fig():
paths = ["M 0.2 0.35 L 0.48 0.52 L 0.52 0.50",
"M 0.25 0.75 L 0.475 0.52 L 0.52 0.52",
"M 0.5 0.9 L 0.485 0.52 L 0.515 0.52",
"M 0.75 0.75 L 0.485 0.52 L 0.52 0.51",
"M 0.8 0.35 L 0.48 0.50 L 0.52 0.52"]
figs = []
values_ = ["No Traffic on Johor-Singapore Causeway", "Low Traffic on Johor-Singapore Causeway", "Johor-Singapore Causeway Slightly Busy",
"Johor-Singapore Causeway Moderately Busy", "Busiest Time to Travel on Johor-Singapore Causeway"]
for i in range(5):
plot_bgcolor = "#def"
colors = ["#f25829", "#f2a529", "#eff229", "#85e043", "#2bad4e","rgba(0,0,0,0)"]
quadrant_text = ["Heavy", "Moderate", "Mild", "Low", "None",""]
n_quadrants = len(colors) - 1
figure_1 = go.Figure(
data=[
go.Pie(
values=[14,14,14,14,14,30],
rotation=130,
hole=0.75,
marker_colors=colors,
marker_line={"width":2, "color":"white"},
textinfo="none",
text=quadrant_text,
hoverinfo="text"
),
],
layout=go.Layout(
showlegend=False,
margin=dict(b=0,t=30,l=10,r=10),
width=500,
height=350,
paper_bgcolor="rgba(0,0,0,0)",
annotations=[
go.layout.Annotation(
text=f"{values_[i]}",
x=0.5, xanchor="center", xref="paper",
y= 0.1, yanchor="bottom", yref="paper",
showarrow=False,
font= {"size":15, "color":"#333"}
)
]
)
)
figure_1.update_layout(shapes=[dict(type='path',
path=paths[i],
fillcolor="#333"),
go.layout.Shape(
type="circle",
x0=0.48, x1=0.52,
y0=0.48, y1=0.54,
fillcolor="#333",
line_color="#333",
)])
figs.append(figure_1)
return figs
def predicted_figure(clf, x, figs):
result = create_row(x[0], x[1], x[2], x[3])
pred_val = clf.predict(result)[0]
return figs[pred_val]
def get_today():
t = str(date.today()).split('-')
today = []
for i in t:
if t[0] =='0':
today.append(int(t[1:]))
else:
today.append(int(i))
return today
def update_output(date_value):
string_prefix = 'Travel Day: '
if date_value is not None:
date_string = convert_date(date_value)
return string_prefix + date_string
def update_final_output_hour(starter_variables, my_date_picker_single, hours_dropdown_id, direction_id):
# starter_variables = [clf, str(date.today()), "07:00", "Tuas-Johor"]
starter_variables[1] = str(my_date_picker_single)
starter_variables[2] = str(hours_dropdown_id)
starter_variables[3] = str(direction_id)
fig = predicted_figure(starter_variables)
return fig
def train_model(x_train, y_train):
clf = MLPClassifier(solver='lbfgs', alpha=3, hidden_layer_sizes=(5,4), random_state=2, max_iter=3000)
clf.fit(x_train, y_train)
return clf
def pred_bars(my_date_picker_single, final_table):
day_today = convert_date(str(my_date_picker_single))
df_filter = final_table[final_table['day']==day_today]
color_map = {0:"#2bad4e", 1:"#85e043", 2:"#eff229", 3:"#f2a529", 4:"#f25829"}
bar_day = make_subplots(shared_yaxes="all", rows=2, cols=2, start_cell="bottom-left", subplot_titles=("Johor-Tuas",
"Tuas-Johor",
"Johor-Woodlands",
"Woodlands-Johor"))
f1 = df_filter[df_filter['view']=='Johor-Tuas']
c1 = pd.Series(f1['cat']).map(color_map)
bar_day.add_trace(go.Bar(x=f1['hour'], y=f1['vehicle'], name='Johor-Tuas', showlegend=False, marker={'color':c1}),
row=1, col=1)
f2 = df_filter[df_filter['view']=='Tuas-Johor']
c2 = pd.Series(f2['cat']).map(color_map)
bar_day.add_trace(go.Bar(x=f2['hour'], y=f2['vehicle'], name='Tuas-Johor', showlegend=False, marker={'color':c2}),
row=1, col=2)
f3 = df_filter[df_filter['view']=='Johor-Woodlands']
c3 = pd.Series(f3['cat']).map(color_map)
bar_day.add_trace(go.Bar(x=f3['hour'], y=f3['vehicle'], name='Johor-Woodlands', showlegend=False, marker={'color':c3}),
row=2, col=1)
f4 = df_filter[df_filter['view']=='Woodlands-Johor']
c4 = pd.Series(f4['cat']).map(color_map)
bar_day.add_trace(go.Bar(x=f4['hour'], y=f4['vehicle'], name='Woodlands-Johor', showlegend=False, marker={'color':c4}),
row=2, col=2)
val_d = my_date_picker_single.strftime("%d %B, %Y")
day_d = my_date_picker_single.strftime("%A")
tex = "Predicted 24 Hour Traffic Trend on: " + day_d + ", " + str(val_d)
bar_day.update_layout(title_text=tex, paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)")
bar_day.update_xaxes(tickangle=45)
return bar_day