Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -60,17 +60,39 @@ else:
|
|
60 |
|
61 |
def create_choropleth_map(metric, start_date, end_date):
|
62 |
"""Creates a choropleth map for a given metric and date range."""
|
|
|
|
|
63 |
if panel_df is None or 'DUMMY' in panel_df['GEOID'].tolist():
|
64 |
fig, ax = plt.subplots()
|
65 |
ax.text(0.5, 0.5, "Data not loaded", ha='center', va='center')
|
66 |
return fig
|
67 |
|
68 |
-
|
69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
|
71 |
filtered_df = panel_df[(panel_df['month'] >= start_date) & (panel_df['month'] <= end_date)]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
geoid_totals = filtered_df.groupby('GEOID')[metric].sum().reset_index()
|
|
|
74 |
|
75 |
merged_gdf = tracts_gdf.merge(geoid_totals, on='GEOID', how='left').fillna(0)
|
76 |
|
@@ -88,17 +110,38 @@ def create_choropleth_map(metric, start_date, end_date):
|
|
88 |
|
89 |
def create_time_series_plot(metric, start_date, end_date):
|
90 |
"""Creates a time series plot for a given metric and date range."""
|
|
|
|
|
91 |
if panel_df is None or 'DUMMY' in panel_df['GEOID'].tolist():
|
92 |
fig, ax = plt.subplots()
|
93 |
ax.text(0.5, 0.5, "Data not loaded", ha='center', va='center')
|
94 |
return fig
|
95 |
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
|
99 |
filtered_df = panel_df[(panel_df['month'] >= start_date) & (panel_df['month'] <= end_date)]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
monthly_totals = filtered_df.groupby('month')[metric].sum()
|
|
|
102 |
|
103 |
fig, ax = plt.subplots(figsize=(12, 6))
|
104 |
monthly_totals.plot(ax=ax)
|
@@ -192,49 +235,58 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
192 |
choices=['crime_total', 'sr311_total', 'dob_permits_total'],
|
193 |
value='crime_total'
|
194 |
)
|
195 |
-
|
196 |
-
|
|
|
|
|
197 |
|
198 |
-
start_date_picker = gr.
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
|
201 |
update_button = gr.Button("Update Dashboard")
|
202 |
|
203 |
with gr.Column(scale=3):
|
204 |
gr.Markdown("### Visualizations")
|
205 |
-
|
206 |
-
|
207 |
-
initial_ts = create_time_series_plot('crime_total', min_date, max_date)
|
208 |
-
|
209 |
-
map_plot = gr.Plot(value=initial_map)
|
210 |
-
ts_plot = gr.Plot(value=initial_ts)
|
211 |
|
212 |
-
# Function to update both plots
|
213 |
-
def
|
|
|
214 |
map_fig = create_choropleth_map(metric, start_date, end_date)
|
215 |
ts_fig = create_time_series_plot(metric, start_date, end_date)
|
216 |
return map_fig, ts_fig
|
217 |
|
218 |
-
# Update
|
219 |
update_button.click(
|
220 |
-
fn=
|
221 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
222 |
outputs=[map_plot, ts_plot]
|
223 |
)
|
224 |
|
225 |
-
# Also
|
226 |
metric_selector.change(
|
227 |
-
fn=
|
228 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
229 |
outputs=[map_plot, ts_plot]
|
230 |
)
|
|
|
231 |
start_date_picker.change(
|
232 |
-
fn=
|
233 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
234 |
outputs=[map_plot, ts_plot]
|
235 |
)
|
|
|
236 |
end_date_picker.change(
|
237 |
-
fn=
|
238 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
239 |
outputs=[map_plot, ts_plot]
|
240 |
)
|
|
|
60 |
|
61 |
def create_choropleth_map(metric, start_date, end_date):
|
62 |
"""Creates a choropleth map for a given metric and date range."""
|
63 |
+
print(f"DEBUG: create_choropleth_map called with metric={metric}, start_date={start_date}, end_date={end_date}")
|
64 |
+
|
65 |
if panel_df is None or 'DUMMY' in panel_df['GEOID'].tolist():
|
66 |
fig, ax = plt.subplots()
|
67 |
ax.text(0.5, 0.5, "Data not loaded", ha='center', va='center')
|
68 |
return fig
|
69 |
|
70 |
+
# Parse dates - handle both string and datetime inputs
|
71 |
+
try:
|
72 |
+
if isinstance(start_date, str):
|
73 |
+
start_date = pd.to_datetime(start_date)
|
74 |
+
if isinstance(end_date, str):
|
75 |
+
end_date = pd.to_datetime(end_date)
|
76 |
+
|
77 |
+
print(f"DEBUG: Parsed dates - start: {start_date}, end: {end_date}")
|
78 |
+
|
79 |
+
except Exception as e:
|
80 |
+
print(f"DEBUG: Date parsing error: {e}")
|
81 |
+
start_date = panel_df['month'].min()
|
82 |
+
end_date = panel_df['month'].max()
|
83 |
|
84 |
filtered_df = panel_df[(panel_df['month'] >= start_date) & (panel_df['month'] <= end_date)]
|
85 |
+
print(f"DEBUG: Filtered dataframe length: {len(filtered_df)}")
|
86 |
+
|
87 |
+
if len(filtered_df) == 0:
|
88 |
+
fig, ax = plt.subplots(1, 1, figsize=(10, 10))
|
89 |
+
ax.text(0.5, 0.5, f"No data found for date range", ha='center', va='center')
|
90 |
+
ax.set_title('No Data Available', fontsize=15)
|
91 |
+
ax.set_axis_off()
|
92 |
+
return fig
|
93 |
|
94 |
geoid_totals = filtered_df.groupby('GEOID')[metric].sum().reset_index()
|
95 |
+
print(f"DEBUG: GEOID totals shape: {geoid_totals.shape}")
|
96 |
|
97 |
merged_gdf = tracts_gdf.merge(geoid_totals, on='GEOID', how='left').fillna(0)
|
98 |
|
|
|
110 |
|
111 |
def create_time_series_plot(metric, start_date, end_date):
|
112 |
"""Creates a time series plot for a given metric and date range."""
|
113 |
+
print(f"DEBUG: create_time_series_plot called with metric={metric}, start_date={start_date}, end_date={end_date}")
|
114 |
+
|
115 |
if panel_df is None or 'DUMMY' in panel_df['GEOID'].tolist():
|
116 |
fig, ax = plt.subplots()
|
117 |
ax.text(0.5, 0.5, "Data not loaded", ha='center', va='center')
|
118 |
return fig
|
119 |
|
120 |
+
# Parse dates - handle both string and datetime inputs
|
121 |
+
try:
|
122 |
+
if isinstance(start_date, str):
|
123 |
+
start_date = pd.to_datetime(start_date)
|
124 |
+
if isinstance(end_date, str):
|
125 |
+
end_date = pd.to_datetime(end_date)
|
126 |
+
|
127 |
+
print(f"DEBUG: Parsed dates - start: {start_date}, end: {end_date}")
|
128 |
+
|
129 |
+
except Exception as e:
|
130 |
+
print(f"DEBUG: Date parsing error: {e}")
|
131 |
+
start_date = panel_df['month'].min()
|
132 |
+
end_date = panel_df['month'].max()
|
133 |
|
134 |
filtered_df = panel_df[(panel_df['month'] >= start_date) & (panel_df['month'] <= end_date)]
|
135 |
+
print(f"DEBUG: Filtered dataframe length: {len(filtered_df)}")
|
136 |
+
|
137 |
+
if len(filtered_df) == 0:
|
138 |
+
fig, ax = plt.subplots(figsize=(12, 6))
|
139 |
+
ax.text(0.5, 0.5, f"No data found for date range", ha='center', va='center')
|
140 |
+
ax.set_title('No Data Available', fontsize=15)
|
141 |
+
return fig
|
142 |
|
143 |
monthly_totals = filtered_df.groupby('month')[metric].sum()
|
144 |
+
print(f"DEBUG: Monthly totals shape: {monthly_totals.shape}")
|
145 |
|
146 |
fig, ax = plt.subplots(figsize=(12, 6))
|
147 |
monthly_totals.plot(ax=ax)
|
|
|
235 |
choices=['crime_total', 'sr311_total', 'dob_permits_total'],
|
236 |
value='crime_total'
|
237 |
)
|
238 |
+
|
239 |
+
# Get date range from data
|
240 |
+
min_date = panel_df['month'].min().strftime('%Y-%m-%d')
|
241 |
+
max_date = panel_df['month'].max().strftime('%Y-%m-%d')
|
242 |
|
243 |
+
start_date_picker = gr.Textbox(
|
244 |
+
label="Start Date (YYYY-MM-DD)",
|
245 |
+
value=min_date,
|
246 |
+
placeholder="2023-01-01"
|
247 |
+
)
|
248 |
+
end_date_picker = gr.Textbox(
|
249 |
+
label="End Date (YYYY-MM-DD)",
|
250 |
+
value=max_date,
|
251 |
+
placeholder="2023-12-31"
|
252 |
+
)
|
253 |
|
254 |
update_button = gr.Button("Update Dashboard")
|
255 |
|
256 |
with gr.Column(scale=3):
|
257 |
gr.Markdown("### Visualizations")
|
258 |
+
map_plot = gr.Plot()
|
259 |
+
ts_plot = gr.Plot()
|
|
|
|
|
|
|
|
|
260 |
|
261 |
+
# Function to update both plots at once
|
262 |
+
def update_dashboard(metric, start_date, end_date):
|
263 |
+
print(f"DEBUG: update_dashboard called with {metric}, {start_date}, {end_date}")
|
264 |
map_fig = create_choropleth_map(metric, start_date, end_date)
|
265 |
ts_fig = create_time_series_plot(metric, start_date, end_date)
|
266 |
return map_fig, ts_fig
|
267 |
|
268 |
+
# Update on button click
|
269 |
update_button.click(
|
270 |
+
fn=update_dashboard,
|
271 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
272 |
outputs=[map_plot, ts_plot]
|
273 |
)
|
274 |
|
275 |
+
# Also trigger updates when inputs change
|
276 |
metric_selector.change(
|
277 |
+
fn=update_dashboard,
|
278 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
279 |
outputs=[map_plot, ts_plot]
|
280 |
)
|
281 |
+
|
282 |
start_date_picker.change(
|
283 |
+
fn=update_dashboard,
|
284 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
285 |
outputs=[map_plot, ts_plot]
|
286 |
)
|
287 |
+
|
288 |
end_date_picker.change(
|
289 |
+
fn=update_dashboard,
|
290 |
inputs=[metric_selector, start_date_picker, end_date_picker],
|
291 |
outputs=[map_plot, ts_plot]
|
292 |
)
|