Spaces:
Sleeping
Sleeping
tappyness1
commited on
Commit
·
ae3451c
1
Parent(s):
54e1064
update to charts
Browse files- app.py +29 -13
- src/basic_plot.py +65 -22
- src/data_ingestion.py +29 -0
- src/heatmap.py +73 -42
- src/map_viz.py +2 -0
app.py
CHANGED
@@ -7,6 +7,7 @@ from src.basic_plot import basic_chart
|
|
7 |
from src.map_viz import calling_map_viz
|
8 |
from src.data_ingestion import daily_average
|
9 |
from src.heatmap import HeatMap
|
|
|
10 |
|
11 |
def fetch_data():
|
12 |
# comment out for local testing, but be sure to include after testing
|
@@ -21,8 +22,9 @@ def fetch_data():
|
|
21 |
return counts_df
|
22 |
|
23 |
def main():
|
24 |
-
|
25 |
counts_df = fetch_data()
|
|
|
|
|
26 |
# st.set_page_config(layout="wide")
|
27 |
height = 650
|
28 |
|
@@ -38,34 +40,48 @@ def main():
|
|
38 |
checkbox_one = st.sidebar.checkbox('Overall Traffic', value = True) # rename as necessary
|
39 |
checkbox_two = st.sidebar.checkbox('Traffic Map', value = True)
|
40 |
checkbox_three = st.sidebar.checkbox('Heat Map', value = True)
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
if checkbox_one:
|
43 |
-
st.
|
|
|
|
|
44 |
|
45 |
if checkbox_two:
|
|
|
46 |
st.pyplot(calling_map_viz(counts_df))
|
47 |
|
48 |
if checkbox_three:
|
49 |
|
50 |
heatmap = HeatMap(counts_df)
|
51 |
-
|
52 |
-
st.
|
|
|
|
|
53 |
st.plotly_chart(heatmap.heatmap())
|
54 |
-
|
55 |
-
hour_choice = st.selectbox(
|
56 |
-
"Choose Hour",
|
57 |
-
options=[
|
58 |
"00:00", "01:00", "02:00", "03:00", "04:00", "05:00",
|
59 |
"06:00", "07:00", "08:00", "09:00", "10:00", "11:00",
|
60 |
"12:00", "13:00", "14:00", "15:00", "16:00", "17:00",
|
61 |
"18:00", "19:00", "20:00", "21:00", "22:00", "23:00",
|
62 |
-
]
|
63 |
-
|
|
|
|
|
|
|
64 |
)
|
|
|
|
|
65 |
st.plotly_chart(heatmap.update_hour_bar_chart(hour_choice))
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
69 |
st.plotly_chart(heatmap.update_day_bar_chart(day_choice))
|
70 |
|
71 |
|
|
|
7 |
from src.map_viz import calling_map_viz
|
8 |
from src.data_ingestion import daily_average
|
9 |
from src.heatmap import HeatMap
|
10 |
+
from src.data_ingestion import remove_previous_view, merge_volumes
|
11 |
|
12 |
def fetch_data():
|
13 |
# comment out for local testing, but be sure to include after testing
|
|
|
22 |
return counts_df
|
23 |
|
24 |
def main():
|
|
|
25 |
counts_df = fetch_data()
|
26 |
+
counts_df = remove_previous_view(counts_df)
|
27 |
+
counts_df = merge_volumes(counts_df)
|
28 |
# st.set_page_config(layout="wide")
|
29 |
height = 650
|
30 |
|
|
|
40 |
checkbox_one = st.sidebar.checkbox('Overall Traffic', value = True) # rename as necessary
|
41 |
checkbox_two = st.sidebar.checkbox('Traffic Map', value = True)
|
42 |
checkbox_three = st.sidebar.checkbox('Heat Map', value = True)
|
43 |
+
view_options = list(counts_df["view"].unique())
|
44 |
+
view_options.append('All')
|
45 |
+
view = st.sidebar.selectbox("Choose View", options=view_options, index = view_options.index("Woodlands - to Johor"))
|
46 |
+
if view != 'All':
|
47 |
+
st.header(f"Showing Traffic for {view}")
|
48 |
+
counts_df = counts_df[counts_df['view'] == view]
|
49 |
|
50 |
if checkbox_one:
|
51 |
+
st.subheader("Overall Traffic")
|
52 |
+
plot = st.selectbox("Choose Plot", options=["Day", "Hour", "Raw"], index = 0)
|
53 |
+
st.plotly_chart(basic_chart(counts_df, plot = plot),use_container_width=True)
|
54 |
|
55 |
if checkbox_two:
|
56 |
+
st.subheader("Traffic Map")
|
57 |
st.pyplot(calling_map_viz(counts_df))
|
58 |
|
59 |
if checkbox_three:
|
60 |
|
61 |
heatmap = HeatMap(counts_df)
|
62 |
+
|
63 |
+
# st.header("Mean Vehicle Count by Day of Week")
|
64 |
+
# st.plotly_chart(heatmap.vehicle_count_bar())
|
65 |
+
st.subheader("Heatmap")
|
66 |
st.plotly_chart(heatmap.heatmap())
|
67 |
+
hours = [
|
|
|
|
|
|
|
68 |
"00:00", "01:00", "02:00", "03:00", "04:00", "05:00",
|
69 |
"06:00", "07:00", "08:00", "09:00", "10:00", "11:00",
|
70 |
"12:00", "13:00", "14:00", "15:00", "16:00", "17:00",
|
71 |
"18:00", "19:00", "20:00", "21:00", "22:00", "23:00",
|
72 |
+
]
|
73 |
+
hour_choice = st.selectbox(
|
74 |
+
"Choose Hour",
|
75 |
+
options= hours,
|
76 |
+
key = "hour", index = hours.index("08:00")
|
77 |
)
|
78 |
+
|
79 |
+
st.subheader(f"Traffic Volume of Each Day at {hour_choice}")
|
80 |
st.plotly_chart(heatmap.update_hour_bar_chart(hour_choice))
|
81 |
+
days = ["Monday", "Tuesday", "Wednesday",
|
82 |
+
"Thursday", "Friday","Saturday", "Sunday"]
|
83 |
+
day_choice = st.selectbox("Choose Day of the Week", options = days, key = "day", index = days.index("Saturday"))
|
84 |
+
st.subheader(f"Traffic Volume of Each Hour on {day_choice}")
|
85 |
st.plotly_chart(heatmap.update_day_bar_chart(day_choice))
|
86 |
|
87 |
|
src/basic_plot.py
CHANGED
@@ -4,27 +4,70 @@ import plotly.express as px
|
|
4 |
from datasets import load_dataset
|
5 |
import os
|
6 |
|
7 |
-
|
8 |
-
|
9 |
# data processing
|
10 |
-
counts_df[
|
11 |
-
|
12 |
-
|
13 |
-
counts_df[
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
22 |
# conditional views
|
23 |
-
if plot ==
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
from datasets import load_dataset
|
5 |
import os
|
6 |
|
7 |
+
def basic_chart(counts_df, plot, hovermode = False):
|
8 |
+
|
9 |
# data processing
|
10 |
+
counts_df["traffic"] = (
|
11 |
+
counts_df["car"] + counts_df["motorcycle"] + counts_df["large_vehicle"]
|
12 |
+
)
|
13 |
+
counts_df["datetime"] = pd.to_datetime(counts_df["date"] + " " + counts_df["time"])
|
14 |
+
counts_df["weekday"] = counts_df["datetime"].dt.strftime("%A")
|
15 |
+
counts_df["hour"] = counts_df["datetime"].dt.strftime("%H")
|
16 |
+
|
17 |
+
# print (counts_df.head())
|
18 |
+
|
19 |
+
# get the mean by the weekday
|
20 |
+
date_view = counts_df.groupby(by=["view", "weekday"]).mean().round(1)
|
21 |
+
date_view = date_view.reset_index()
|
22 |
+
|
23 |
+
# get the mean by the time
|
24 |
+
time_view = counts_df.groupby(by=["view", "hour"]).mean().round(1)
|
25 |
+
time_view = time_view.reset_index()
|
26 |
+
|
27 |
# conditional views
|
28 |
+
if plot == "Day":
|
29 |
+
# filtered_view_day = date_view[date_view["view"] == view]
|
30 |
+
fig = px.bar(
|
31 |
+
date_view,
|
32 |
+
x="weekday",
|
33 |
+
y="traffic",
|
34 |
+
category_orders = {'weekday': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']},
|
35 |
+
labels={
|
36 |
+
"weekday": "Day",
|
37 |
+
"traffic": "Traffic",
|
38 |
+
},
|
39 |
+
)
|
40 |
+
fig.update_layout(
|
41 |
+
yaxis_visible=True, yaxis_showticklabels=False, hovermode=hovermode, xaxis_title = '', yaxis_title = ''
|
42 |
+
)
|
43 |
+
elif plot == "Hour":
|
44 |
+
# filterd_view_time = time_view[time_view["view"] == view]
|
45 |
+
fig = px.bar(
|
46 |
+
time_view,
|
47 |
+
x="hour",
|
48 |
+
y="traffic",
|
49 |
+
labels={
|
50 |
+
"hour": "Hour",
|
51 |
+
"traffic": "Traffic",
|
52 |
+
},
|
53 |
+
)
|
54 |
+
fig.update_layout(
|
55 |
+
yaxis_visible=True, yaxis_showticklabels=False, hovermode=hovermode
|
56 |
+
)
|
57 |
+
fig.update_xaxes(tickmode = 'linear', type = 'category')
|
58 |
+
elif plot == "Raw":
|
59 |
+
# filtered_views = counts_df[counts_df["view"] == view]
|
60 |
+
fig = px.bar(
|
61 |
+
counts_df,
|
62 |
+
x="datetime",
|
63 |
+
y="traffic",
|
64 |
+
labels={
|
65 |
+
"datetime": "Date and Time",
|
66 |
+
"traffic": "Traffic",
|
67 |
+
},
|
68 |
+
)
|
69 |
+
fig.update_layout(
|
70 |
+
yaxis_visible=True, yaxis_showticklabels=False, hovermode=hovermode
|
71 |
+
)
|
72 |
+
|
73 |
+
return fig
|
src/data_ingestion.py
CHANGED
@@ -1,6 +1,35 @@
|
|
1 |
import pandas as pd
|
2 |
import numpy as np
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
def daily_average(counts_df):
|
5 |
|
6 |
filtered_views_list = ['View_from_Second_Link_at_Tuas_to_sg',
|
|
|
1 |
import pandas as pd
|
2 |
import numpy as np
|
3 |
|
4 |
+
def remove_previous_view(counts_df):
|
5 |
+
filtered_views_list = ['View_from_Second_Link_at_Tuas_to_sg',
|
6 |
+
'View_from_Second_Link_at_Tuas_to_jh',
|
7 |
+
'View_from_Tuas_Checkpoint_to_sg',
|
8 |
+
'View_from_Tuas_Checkpoint_to_jh',
|
9 |
+
'View_from_Woodlands_Causeway_Towards_Johor_to_sg',
|
10 |
+
'View_from_Woodlands_Causeway_Towards_Johor_to_jh',
|
11 |
+
'View_from_Woodlands_Checkpoint_Towards_BKE_to_sg',
|
12 |
+
'View_from_Woodlands_Checkpoint_Towards_BKE_to_jh']
|
13 |
+
counts_df = counts_df[counts_df['view'].isin(filtered_views_list)]
|
14 |
+
return counts_df
|
15 |
+
|
16 |
+
def merge_volumes(counts_df):
|
17 |
+
merge_groups = {"Tuas - to SG": ["View_from_Second_Link_at_Tuas_to_sg", "View_from_Tuas_Checkpoint_to_sg"],
|
18 |
+
"Tuas - to Johor": ['View_from_Second_Link_at_Tuas_to_jh', 'View_from_Tuas_Checkpoint_to_jh'],
|
19 |
+
"Woodlands - to SG": ['View_from_Woodlands_Causeway_Towards_Johor_to_sg', 'View_from_Woodlands_Checkpoint_Towards_BKE_to_sg'],
|
20 |
+
"Woodlands - to Johor": ['View_from_Woodlands_Causeway_Towards_Johor_to_jh', 'View_from_Woodlands_Checkpoint_Towards_BKE_to_jh']}
|
21 |
+
def apply_merge_groups(row):
|
22 |
+
for key, value in merge_groups.items():
|
23 |
+
if row in value:
|
24 |
+
return key
|
25 |
+
counts_df['merge_group'] = counts_df['view'].apply(apply_merge_groups)
|
26 |
+
counts_df = counts_df.groupby(by = ['merge_group', 'date', 'time']).sum(numeric_only = True)
|
27 |
+
counts_df = counts_df.reset_index()
|
28 |
+
counts_df = counts_df.rename(columns={"merge_group": "view"})
|
29 |
+
|
30 |
+
return counts_df
|
31 |
+
|
32 |
+
|
33 |
def daily_average(counts_df):
|
34 |
|
35 |
filtered_views_list = ['View_from_Second_Link_at_Tuas_to_sg',
|
src/heatmap.py
CHANGED
@@ -7,6 +7,7 @@ import plotly.express as px
|
|
7 |
from plotly.subplots import make_subplots
|
8 |
import plotly.graph_objects as go
|
9 |
import streamlit as st
|
|
|
10 |
|
11 |
|
12 |
def clean_data(df):
|
@@ -22,21 +23,27 @@ def clean_data(df):
|
|
22 |
|
23 |
class HeatMap:
|
24 |
def __init__(self, counts_df):
|
|
|
|
|
|
|
25 |
self.df = clean_data(counts_df)
|
|
|
26 |
new = (
|
27 |
self.df.groupby(["hour", "day"])
|
28 |
-
.
|
29 |
.drop(columns=["car", "large_vehicle"])
|
30 |
.reset_index()
|
31 |
)
|
|
|
32 |
table = pd.pivot_table(
|
33 |
new, values="vehicle", index=["day"], columns=["hour"]
|
34 |
).reset_index()
|
35 |
-
|
|
|
36 |
|
37 |
|
38 |
def vehicle_count_bar(self):
|
39 |
-
new_df = self.df.groupby(["day"]).
|
40 |
new_df = new_df.reindex([1, 5, 6, 4, 0, 2, 3])
|
41 |
|
42 |
veh_count_fig = px.bar(
|
@@ -47,6 +54,7 @@ class HeatMap:
|
|
47 |
text_auto=True,
|
48 |
labels={"day": "Day of the Week", "vehicle": "Vehicle Count"},
|
49 |
)
|
|
|
50 |
|
51 |
return veh_count_fig
|
52 |
|
@@ -57,59 +65,71 @@ class HeatMap:
|
|
57 |
hm_fig = px.imshow(
|
58 |
new_table,
|
59 |
labels=dict(
|
60 |
-
x="Hour of the Day", y="Day of the Week", color="
|
61 |
),
|
62 |
x=[
|
63 |
-
"
|
64 |
-
"
|
65 |
-
"
|
66 |
-
"
|
67 |
-
"
|
68 |
-
"
|
69 |
-
"
|
70 |
-
"
|
71 |
-
"
|
72 |
-
"
|
73 |
-
"
|
74 |
-
"
|
75 |
-
"
|
76 |
-
"
|
77 |
-
"
|
78 |
-
"
|
79 |
-
"
|
80 |
-
"
|
81 |
-
"
|
82 |
-
"
|
83 |
-
"
|
84 |
-
"
|
85 |
-
"
|
86 |
-
"
|
87 |
],
|
88 |
y=[
|
89 |
-
"
|
90 |
-
"
|
91 |
-
"
|
92 |
-
"
|
93 |
-
"
|
94 |
-
"
|
95 |
-
"
|
96 |
],
|
97 |
-
text_auto=True,
|
|
|
|
|
|
|
|
|
|
|
98 |
)
|
99 |
-
hm_fig.update_xaxes(side="top")
|
100 |
-
|
101 |
return hm_fig
|
102 |
|
103 |
def update_hour_bar_chart(self, hour="08:00"):
|
104 |
-
|
105 |
fig_hours = px.bar(
|
106 |
self.table,
|
107 |
x="day",
|
108 |
y=str(hour),
|
109 |
color="day",
|
110 |
-
text_auto=True,
|
111 |
labels={"day": "Day of the Week"},
|
112 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
return fig_hours
|
114 |
|
115 |
def update_day_bar_chart(self, day="Saturday"):
|
@@ -127,13 +147,24 @@ class HeatMap:
|
|
127 |
]
|
128 |
t = t.reset_index()
|
129 |
|
|
|
|
|
130 |
fig_days = px.bar(
|
131 |
t,
|
132 |
x="hour",
|
133 |
y=str(day),
|
134 |
color=str(day),
|
135 |
-
text_auto=True,
|
136 |
labels={"hour": "Count of Each Hour"},
|
137 |
)
|
138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
return fig_days
|
|
|
7 |
from plotly.subplots import make_subplots
|
8 |
import plotly.graph_objects as go
|
9 |
import streamlit as st
|
10 |
+
from src.data_ingestion import remove_previous_view, merge_volumes
|
11 |
|
12 |
|
13 |
def clean_data(df):
|
|
|
23 |
|
24 |
class HeatMap:
|
25 |
def __init__(self, counts_df):
|
26 |
+
|
27 |
+
# counts_df = counts_df[counts_df['view'] == view]
|
28 |
+
|
29 |
self.df = clean_data(counts_df)
|
30 |
+
|
31 |
new = (
|
32 |
self.df.groupby(["hour", "day"])
|
33 |
+
.mean(numeric_only = True)
|
34 |
.drop(columns=["car", "large_vehicle"])
|
35 |
.reset_index()
|
36 |
)
|
37 |
+
|
38 |
table = pd.pivot_table(
|
39 |
new, values="vehicle", index=["day"], columns=["hour"]
|
40 |
).reset_index()
|
41 |
+
|
42 |
+
self.table = table.reindex([1, 5, 6, 4, 0, 2, 3]).round(1)
|
43 |
|
44 |
|
45 |
def vehicle_count_bar(self):
|
46 |
+
new_df = self.df.groupby(["day"]).mean(numeric_only = True).round(1).reset_index()
|
47 |
new_df = new_df.reindex([1, 5, 6, 4, 0, 2, 3])
|
48 |
|
49 |
veh_count_fig = px.bar(
|
|
|
54 |
text_auto=True,
|
55 |
labels={"day": "Day of the Week", "vehicle": "Vehicle Count"},
|
56 |
)
|
57 |
+
veh_count_fig.update_layout(showlegend=False)
|
58 |
|
59 |
return veh_count_fig
|
60 |
|
|
|
65 |
hm_fig = px.imshow(
|
66 |
new_table,
|
67 |
labels=dict(
|
68 |
+
x="Hour of the Day", y="Day of the Week", color="Traffic"
|
69 |
),
|
70 |
x=[
|
71 |
+
"00",
|
72 |
+
"01",
|
73 |
+
"02",
|
74 |
+
"03",
|
75 |
+
"04",
|
76 |
+
"05",
|
77 |
+
"06",
|
78 |
+
"07",
|
79 |
+
"08",
|
80 |
+
"09",
|
81 |
+
"10",
|
82 |
+
"11",
|
83 |
+
"12",
|
84 |
+
"13",
|
85 |
+
"14",
|
86 |
+
"15",
|
87 |
+
"16",
|
88 |
+
"17",
|
89 |
+
"18",
|
90 |
+
"19",
|
91 |
+
"20",
|
92 |
+
"21",
|
93 |
+
"22",
|
94 |
+
"23",
|
95 |
],
|
96 |
y=[
|
97 |
+
"Mon",
|
98 |
+
"Tue",
|
99 |
+
"Wed",
|
100 |
+
"Thu",
|
101 |
+
"Fri",
|
102 |
+
"Sat",
|
103 |
+
"Sun",
|
104 |
],
|
105 |
+
# text_auto=True,
|
106 |
+
)
|
107 |
+
hm_fig.update_xaxes(side="top", tickmode = 'linear', type = 'category')
|
108 |
+
hm_fig.update_layout(yaxis_visible=True,
|
109 |
+
yaxis_showticklabels=True,
|
110 |
+
yaxis_title = ''
|
111 |
)
|
|
|
|
|
112 |
return hm_fig
|
113 |
|
114 |
def update_hour_bar_chart(self, hour="08:00"):
|
115 |
+
|
116 |
fig_hours = px.bar(
|
117 |
self.table,
|
118 |
x="day",
|
119 |
y=str(hour),
|
120 |
color="day",
|
121 |
+
# text_auto=True,
|
122 |
labels={"day": "Day of the Week"},
|
123 |
)
|
124 |
+
fig_hours.update_layout(showlegend=False)
|
125 |
+
fig_hours.update_layout(yaxis_visible=False,
|
126 |
+
yaxis_showticklabels=False,
|
127 |
+
yaxis_title = False
|
128 |
+
)
|
129 |
+
fig_hours.update_layout(xaxis_visible=True,
|
130 |
+
xaxis_showticklabels=True,
|
131 |
+
xaxis_title = ''
|
132 |
+
)
|
133 |
return fig_hours
|
134 |
|
135 |
def update_day_bar_chart(self, day="Saturday"):
|
|
|
147 |
]
|
148 |
t = t.reset_index()
|
149 |
|
150 |
+
t['hour'] = t['hour'].str[:2]
|
151 |
+
|
152 |
fig_days = px.bar(
|
153 |
t,
|
154 |
x="hour",
|
155 |
y=str(day),
|
156 |
color=str(day),
|
157 |
+
# text_auto=True,
|
158 |
labels={"hour": "Count of Each Hour"},
|
159 |
)
|
160 |
+
fig_days.update_layout(showlegend=False)
|
161 |
+
fig_days.update_layout(yaxis_visible=False,
|
162 |
+
yaxis_showticklabels=False,
|
163 |
+
yaxis_title = False
|
164 |
+
)
|
165 |
+
fig_days.update_layout(xaxis_visible=True,
|
166 |
+
xaxis_showticklabels=True,
|
167 |
+
xaxis_title = '',
|
168 |
+
)
|
169 |
+
fig_days.update_xaxes(tickangle=0, tickmode = 'linear', type = 'category')
|
170 |
return fig_days
|
src/map_viz.py
CHANGED
@@ -10,6 +10,8 @@ import numpy as np
|
|
10 |
import requests
|
11 |
import pandas as pd
|
12 |
|
|
|
|
|
13 |
|
14 |
def calling_map_viz(counts_df):
|
15 |
r = "svg/snazzy-image-01.svg"
|
|
|
10 |
import requests
|
11 |
import pandas as pd
|
12 |
|
13 |
+
import warnings
|
14 |
+
warnings.filterwarnings("ignore")
|
15 |
|
16 |
def calling_map_viz(counts_df):
|
17 |
r = "svg/snazzy-image-01.svg"
|