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", | |
| "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 |