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