ginnyxxxxxxx commited on
Commit
ca321f9
Β·
1 Parent(s): 3bfdad2
Files changed (1) hide show
  1. app.py +39 -82
app.py CHANGED
@@ -1,12 +1,13 @@
1
  import gradio as gr
2
  import pandas as pd
3
  import folium
4
- import ast
5
 
6
- # ── Data paths ──────────────────────────────────────────────────────────────
7
- STAY_POINTS = "data/demographics_sampled.csv"
8
- POI_PATH = "data/poi_sampled.csv"
9
- DEMO_PATH = "data/demographics_sampled.csv"
 
10
 
11
  AGE_MAP = {1:"<18", 2:"18-24", 3:"25-34", 4:"35-44", 5:"45-54", 6:"55-64", 7:"65+"}
12
  SEX_MAP = {1:"Male", 2:"Female"}
@@ -14,65 +15,38 @@ EDU_MAP = {1:"No HS", 2:"HS Grad", 3:"Some College", 4:"Bachelor's", 5:"Graduate
14
  INC_MAP = {1:"<$10k", 2:"$10-15k", 3:"$15-25k", 4:"$25-35k", 5:"$35-50k",
15
  6:"$50-75k", 7:"$75-100k", 8:"$100-125k", 9:"$125-150k", 10:">$150k"}
16
 
17
- # ── Load data ────────────────────────────────────────────────────────────────
18
  print("Loading data...")
19
- sp = pd.read_csv(STAY_POINTS, nrows=200000)
20
- poi = pd.read_csv(POI_PATH)
21
  demo = pd.read_csv(DEMO_PATH)
22
 
23
- # εŠ θΏ™δΈ€θ‘Œ
24
- sp["poi_id"] = sp["poi_id"].astype(int)
25
- poi["poi_id"] = poi["poi_id"].astype(int)
26
-
27
- sp = sp.merge(poi, on="poi_id", how="left")
28
-
29
- # parse act_types string like "[ 2 15]" β†’ list
30
- def parse_act(x):
31
- try:
32
- return list(map(int, str(x).strip("[]").split()))
33
- except:
34
- return []
35
-
36
- poi["act_types"] = poi["act_types"].apply(parse_act)
37
-
38
- # join stay_points with poi
39
- sp = sp.merge(poi, on="poi_id", how="left")
40
  sp["start_datetime"] = pd.to_datetime(sp["start_datetime"], utc=True)
41
  sp["end_datetime"] = pd.to_datetime(sp["end_datetime"], utc=True)
42
  sp["duration_min"] = ((sp["end_datetime"] - sp["start_datetime"]).dt.total_seconds() / 60).round(1)
43
 
44
- # pick 30 sample agents
45
- sample_agents = sorted(sp["agent_id"].value_counts().head(30).index.tolist())
46
- print(f"Loaded. Sample agents: {sample_agents[:5]}...")
47
-
48
-
49
- # ── Core functions ───────────────────────────────────────────────────────────
50
- def get_agent_data(agent_id):
51
- agent_sp = sp[sp["agent_id"] == agent_id].sort_values("start_datetime")
52
- agent_demo = demo[demo["agent_id"] == agent_id].iloc[0]
53
- return agent_sp, agent_demo
54
-
55
 
 
56
  def build_map(agent_sp):
57
  lat = agent_sp["latitude"].mean()
58
  lon = agent_sp["longitude"].mean()
59
  m = folium.Map(location=[lat, lon], zoom_start=12, tiles="CartoDB positron")
60
 
61
- # trajectory line
62
  coords = list(zip(agent_sp["latitude"], agent_sp["longitude"]))
63
  if len(coords) > 1:
64
  folium.PolyLine(coords, color="#4f86c6", weight=2, opacity=0.6).add_to(m)
65
 
66
- # markers
67
- for i, row in agent_sp.iterrows():
68
  folium.CircleMarker(
69
  location=[row["latitude"], row["longitude"]],
70
- radius=6,
71
- color="#e05c5c",
72
- fill=True,
73
- fill_opacity=0.8,
74
  popup=folium.Popup(
75
- f"<b>{row['name']}</b><br>{row['start_datetime'].strftime('%a %m/%d %H:%M')}<br>{row['duration_min']} min",
 
 
76
  max_width=200
77
  )
78
  ).add_to(m)
@@ -83,61 +57,44 @@ def build_map(agent_sp):
83
  def build_poi_sequence(agent_sp):
84
  lines = []
85
  for _, row in agent_sp.iterrows():
86
- dt = row["start_datetime"]
87
  lines.append(
88
- f"{dt.strftime('%a %m/%d')} {dt.strftime('%H:%M')}–{row['end_datetime'].strftime('%H:%M')}"
89
- f" ({int(row['duration_min'])} min) | {row['name']} | act:{row['act_types']}"
 
90
  )
91
  return "\n".join(lines)
92
 
93
 
94
- def build_demo_text(agent_demo):
95
  return (
96
- f"Age: {AGE_MAP.get(agent_demo['age'], agent_demo['age'])} | "
97
- f"Sex: {SEX_MAP.get(agent_demo['sex'], agent_demo['sex'])} | "
98
- f"Education: {EDU_MAP.get(agent_demo['education'], agent_demo['education'])} | "
99
- f"Income: {INC_MAP.get(agent_demo['hh_income'], agent_demo['hh_income'])}"
100
  )
101
 
102
 
103
  def on_select(agent_id):
104
- agent_sp, agent_demo = get_agent_data(int(agent_id))
105
- map_html = build_map(agent_sp)
106
- poi_seq = build_poi_sequence(agent_sp)
107
- demo_text = build_demo_text(agent_demo)
108
- return map_html, poi_seq, demo_text
109
 
110
 
111
- # ── UI ───────────────────────────────────────────────────────────────────────
112
- with gr.Blocks(title="HiCoTraj Demo", theme=gr.themes.Soft()) as demo_app:
113
  gr.Markdown("## HiCoTraj: Trajectory Visualization")
114
 
115
  with gr.Row():
116
- agent_dropdown = gr.Dropdown(
117
- choices=[str(a) for a in sample_agents],
118
- label="Select Agent",
119
- value=str(sample_agents[0])
120
- )
121
  demo_label = gr.Textbox(label="Ground Truth Demographics", interactive=False)
122
 
123
- with gr.Row():
124
- map_out = gr.HTML(label="Trajectory Map")
125
 
126
- with gr.Row():
127
- poi_out = gr.Textbox(label="POI Sequence", lines=20, interactive=False)
128
-
129
- agent_dropdown.change(
130
- fn=on_select,
131
- inputs=agent_dropdown,
132
- outputs=[map_out, poi_out, demo_label]
133
- )
134
-
135
- # load first agent on startup
136
- demo_app.load(
137
- fn=on_select,
138
- inputs=agent_dropdown,
139
- outputs=[map_out, poi_out, demo_label]
140
- )
141
 
142
  if __name__ == "__main__":
143
- demo_app.launch()
 
1
  import gradio as gr
2
  import pandas as pd
3
  import folium
4
+ import os
5
 
6
+ # ── Data paths ───────────────────────────────────────────────────────────────
7
+ BASE = os.path.dirname(os.path.abspath(__file__))
8
+ STAY_POINTS = os.path.join(BASE, "data", "stay_points_sampled.csv")
9
+ POI_PATH = os.path.join(BASE, "data", "poi_sampled.csv")
10
+ DEMO_PATH = os.path.join(BASE, "data", "demographics_sampled.csv")
11
 
12
  AGE_MAP = {1:"<18", 2:"18-24", 3:"25-34", 4:"35-44", 5:"45-54", 6:"55-64", 7:"65+"}
13
  SEX_MAP = {1:"Male", 2:"Female"}
 
15
  INC_MAP = {1:"<$10k", 2:"$10-15k", 3:"$15-25k", 4:"$25-35k", 5:"$35-50k",
16
  6:"$50-75k", 7:"$75-100k", 8:"$100-125k", 9:"$125-150k", 10:">$150k"}
17
 
18
+ # ── Load ─────────────────────────────────────────────────────────────────────
19
  print("Loading data...")
20
+ sp = pd.read_csv(STAY_POINTS)
21
+ poi = pd.read_csv(POI_PATH)
22
  demo = pd.read_csv(DEMO_PATH)
23
 
24
+ sp = sp.merge(poi, on="poi_id", how="left")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  sp["start_datetime"] = pd.to_datetime(sp["start_datetime"], utc=True)
26
  sp["end_datetime"] = pd.to_datetime(sp["end_datetime"], utc=True)
27
  sp["duration_min"] = ((sp["end_datetime"] - sp["start_datetime"]).dt.total_seconds() / 60).round(1)
28
 
29
+ sample_agents = sorted(sp["agent_id"].unique().tolist())
30
+ print(f"Ready. {len(sample_agents)} agents loaded.")
 
 
 
 
 
 
 
 
 
31
 
32
+ # ── Helpers ───────────────────────────────────────────────────────────────────
33
  def build_map(agent_sp):
34
  lat = agent_sp["latitude"].mean()
35
  lon = agent_sp["longitude"].mean()
36
  m = folium.Map(location=[lat, lon], zoom_start=12, tiles="CartoDB positron")
37
 
 
38
  coords = list(zip(agent_sp["latitude"], agent_sp["longitude"]))
39
  if len(coords) > 1:
40
  folium.PolyLine(coords, color="#4f86c6", weight=2, opacity=0.6).add_to(m)
41
 
42
+ for _, row in agent_sp.iterrows():
 
43
  folium.CircleMarker(
44
  location=[row["latitude"], row["longitude"]],
45
+ radius=6, color="#e05c5c", fill=True, fill_opacity=0.8,
 
 
 
46
  popup=folium.Popup(
47
+ f"<b>{row['name']}</b><br>"
48
+ f"{row['start_datetime'].strftime('%a %m/%d %H:%M')}<br>"
49
+ f"{int(row['duration_min'])} min",
50
  max_width=200
51
  )
52
  ).add_to(m)
 
57
  def build_poi_sequence(agent_sp):
58
  lines = []
59
  for _, row in agent_sp.iterrows():
 
60
  lines.append(
61
+ f"{row['start_datetime'].strftime('%a %m/%d')} "
62
+ f"{row['start_datetime'].strftime('%H:%M')}–{row['end_datetime'].strftime('%H:%M')} "
63
+ f"({int(row['duration_min'])} min) | {row['name']} | {row['act_types']}"
64
  )
65
  return "\n".join(lines)
66
 
67
 
68
+ def build_demo_text(row):
69
  return (
70
+ f"Age: {AGE_MAP.get(row['age'], row['age'])} | "
71
+ f"Sex: {SEX_MAP.get(row['sex'], row['sex'])} | "
72
+ f"Education: {EDU_MAP.get(row['education'], row['education'])} | "
73
+ f"Income: {INC_MAP.get(row['hh_income'], row['hh_income'])}"
74
  )
75
 
76
 
77
  def on_select(agent_id):
78
+ agent_id = int(agent_id)
79
+ agent_sp = sp[sp["agent_id"] == agent_id].sort_values("start_datetime")
80
+ agent_demo = demo[demo["agent_id"] == agent_id].iloc[0]
81
+ return build_map(agent_sp), build_poi_sequence(agent_sp), build_demo_text(agent_demo)
 
82
 
83
 
84
+ # ── UI ────────────────────────────────────────────────────────────────────────
85
+ with gr.Blocks(title="HiCoTraj Demo", theme=gr.themes.Soft()) as app:
86
  gr.Markdown("## HiCoTraj: Trajectory Visualization")
87
 
88
  with gr.Row():
89
+ agent_dd = gr.Dropdown(choices=[str(a) for a in sample_agents],
90
+ label="Select Agent", value=str(sample_agents[0]))
 
 
 
91
  demo_label = gr.Textbox(label="Ground Truth Demographics", interactive=False)
92
 
93
+ map_out = gr.HTML(label="Trajectory Map")
94
+ poi_out = gr.Textbox(label="POI Sequence", lines=20, interactive=False)
95
 
96
+ agent_dd.change(fn=on_select, inputs=agent_dd, outputs=[map_out, poi_out, demo_label])
97
+ app.load(fn=on_select, inputs=agent_dd, outputs=[map_out, poi_out, demo_label])
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  if __name__ == "__main__":
100
+ app.launch()