Spaces:
Sleeping
Sleeping
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 = ["<b>Heavy</b>", "<b>Moderate</b>", "<b>Mild</b>", "<b>Low</b>", "<b>None</b>",""] | |
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"<b>{values_[i]}</b>", | |
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", | |
"Johor-Woodlands")) | |
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='Johor-Woodlands', showlegend=False, marker={'color':c4}), | |
row=2, col=2) | |
val_d = date.today().strftime("%d %B, %Y") | |
day_d = date.today().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 |