Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -81,16 +81,22 @@ def create_severity_violation_chart(df, age_group=None):
|
|
81 |
return fig
|
82 |
|
83 |
def get_top_violations(df, age_group):
|
|
|
84 |
if age_group == 'All Ages':
|
|
|
|
|
85 |
violations = pd.concat([
|
86 |
df['Violation1_Drv1'].value_counts(),
|
87 |
df['Violation1_Drv2'].value_counts()
|
88 |
]).groupby(level=0).sum()
|
89 |
else:
|
|
|
90 |
filtered_df = df[
|
91 |
(df['Age_Group_Drv1'] == age_group) |
|
92 |
(df['Age_Group_Drv2'] == age_group)
|
93 |
]
|
|
|
|
|
94 |
violations = pd.concat([
|
95 |
filtered_df['Violation1_Drv1'].value_counts(),
|
96 |
filtered_df['Violation1_Drv2'].value_counts()
|
@@ -99,7 +105,12 @@ def get_top_violations(df, age_group):
|
|
99 |
# Convert to DataFrame and format
|
100 |
violations_df = violations.reset_index()
|
101 |
violations_df.columns = ['Violation Type', 'Count']
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
103 |
violations_df['Percentage'] = violations_df['Percentage'].map('{:.2f}%'.format)
|
104 |
|
105 |
return violations_df.head()
|
@@ -334,7 +345,7 @@ def main():
|
|
334 |
|
335 |
st.markdown("""
|
336 |
**Team Members:**
|
337 |
-
- Janhavi Tushar Zarapkar
|
338 |
- Hangyue Zhang ([email protected])
|
339 |
- Andrew Nam ([email protected])
|
340 |
- Nirmal Attarde ([email protected])
|
@@ -358,115 +369,144 @@ def main():
|
|
358 |
df['Weather'] = 'Unknown'
|
359 |
|
360 |
# Create tabs for different visualizations
|
361 |
-
tab1, tab2, tab3, tab4, tab5 = st.tabs([
|
|
|
|
|
|
|
|
|
|
|
|
|
362 |
|
363 |
with tab1:
|
364 |
-
#
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
# Create and display chart
|
369 |
-
fig = create_severity_violation_chart(df, selected_age)
|
370 |
-
st.plotly_chart(fig, use_container_width=True)
|
371 |
-
|
372 |
-
# Display statistics
|
373 |
-
if selected_age == 'All Ages':
|
374 |
-
total_incidents = len(df)
|
375 |
-
else:
|
376 |
-
total_incidents = len(df[
|
377 |
-
(df['Age_Group_Drv1'] == selected_age) |
|
378 |
-
(df['Age_Group_Drv2'] == selected_age)
|
379 |
-
])
|
380 |
-
|
381 |
-
# Create two columns for statistics
|
382 |
-
col1, col2 = st.columns(2)
|
383 |
-
|
384 |
-
with col1:
|
385 |
-
st.markdown(f"### Total Incidents")
|
386 |
-
st.markdown(f"**{total_incidents:,}** incidents for {selected_age}")
|
387 |
-
|
388 |
-
with col2:
|
389 |
-
st.markdown("### Top Violations")
|
390 |
-
top_violations = get_top_violations(df, selected_age)
|
391 |
-
st.table(top_violations)
|
392 |
-
|
393 |
-
with tab2:
|
394 |
-
# Year selection for map
|
395 |
-
years = sorted(df['Year'].unique())
|
396 |
-
selected_year = st.selectbox('Select Year:', years)
|
397 |
|
398 |
-
|
399 |
|
400 |
-
with
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
height=800,
|
409 |
-
key=f"map_{selected_year}",
|
410 |
-
returned_objects=["null_drawing"]
|
411 |
-
)
|
412 |
|
413 |
with desc_col:
|
414 |
st.markdown("""
|
415 |
-
|
416 |
-
This interactive
|
417 |
-
1. **Accident Markers**: Red markers indicate individual accidents, with popups displaying the coordinates, date/time, and severity of each incident.
|
418 |
-
2. **Heatmap**: The heatmap highlights accident hotspots with colors ranging from blue (low frequency) to yellow (moderate) and red (high frequency), showing areas with more frequent accidents.
|
419 |
|
420 |
**Key Features:**
|
421 |
-
* **
|
422 |
-
* **
|
|
|
423 |
|
424 |
-
**Color Scheme:**
|
425 |
-
* **
|
426 |
-
* **
|
427 |
|
428 |
-
|
|
|
|
|
|
|
|
|
429 |
""")
|
|
|
|
|
|
|
|
|
|
|
430 |
|
431 |
-
|
432 |
-
with tab3:
|
433 |
-
# Weather condition filter
|
434 |
-
weather = ['All Conditions'] + sorted(df['Weather'].unique())
|
435 |
-
selected_weather = st.selectbox('Select Weather Condition:', weather)
|
436 |
|
437 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
|
439 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
|
441 |
-
with
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
width=None, # Let width be responsive
|
447 |
margin=dict(l=50, r=50, t=50, b=50)
|
448 |
)
|
449 |
-
st.plotly_chart(
|
450 |
|
451 |
with desc_col:
|
452 |
-
st.markdown("""
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
**Insights:**
|
464 |
-
This chart helps uncover:
|
465 |
-
* Annual fluctuations in crash incidents.
|
466 |
-
* Correlations between weather conditions and crash frequencies.
|
467 |
-
* Historical patterns that can guide future safety measures and urban planning decisions
|
468 |
-
""")
|
469 |
-
|
470 |
|
471 |
with tab4:
|
472 |
# Dropdown for Unit Type selection
|
@@ -478,27 +518,12 @@ def main():
|
|
478 |
unit_type_pairs = sorted(list(unit_type_pairs))
|
479 |
unit_type = st.selectbox("Select Unit Type Pair", options=['Total'] + unit_type_pairs)
|
480 |
|
481 |
-
# # Create 5th Visualization: Injuries and fatalities chart
|
482 |
-
# injuries_fatalities_chart = create_injuries_fatalities_chart(df, unit_type)
|
483 |
-
# st.altair_chart(injuries_fatalities_chart, use_container_width=True)
|
484 |
-
|
485 |
-
# st.markdown("""
|
486 |
-
# This line chart shows the **total number of injuries and fatalities by month for the selected unit type pair**. The blue line represents total injuries, while the red line represents total fatalities. Observing the trends over the months can help identify any seasonal patterns or peaks in traffic incidents involving specific unit types.
|
487 |
-
|
488 |
-
# - **Total Injuries**: The blue line indicates how injuries vary over different months, highlighting any particular spikes or declines.
|
489 |
-
# - **Total Fatalities**: The red line shows the trend for fatalities, which is generally much lower compared to injuries.
|
490 |
-
# - **Unit Types**: The dropdown selection allows users to filter the data by specific unit type pairs (e.g., Driver vs Pedestrian) or view the overall trend across all types.
|
491 |
-
|
492 |
-
# This visualization aims to provide an intuitive understanding of how injuries and fatalities are distributed across the year, helping stakeholders develop targeted safety measures.
|
493 |
-
# """)
|
494 |
-
|
495 |
chart_col, desc_col = st.columns([7, 3])
|
496 |
|
497 |
with chart_col:
|
498 |
-
# Create 5th Visualization: Injuries and fatalities chart
|
499 |
injuries_fatalities_chart = create_injuries_fatalities_chart(df, unit_type)
|
500 |
injuries_fatalities_chart = injuries_fatalities_chart.properties(
|
501 |
-
height=800
|
502 |
)
|
503 |
st.altair_chart(injuries_fatalities_chart, use_container_width=True)
|
504 |
|
@@ -532,49 +557,92 @@ def main():
|
|
532 |
|
533 |
This visualization aids stakeholders in developing effective safety measures and resource allocation strategies throughout the year.
|
534 |
""")
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
with tab5:
|
539 |
-
|
540 |
-
|
541 |
-
'Collisionmanner',
|
542 |
-
'Lightcondition',
|
543 |
-
'Weather',
|
544 |
-
'SurfaceCondition',
|
545 |
-
'AlcoholUse_Drv1',
|
546 |
-
'Gender_Drv1',
|
547 |
-
]
|
548 |
-
selected_category = st.selectbox("Select Category:", categories)
|
549 |
-
|
550 |
-
# Dropdown for year selection
|
551 |
-
years = ['All Years'] + sorted(df['Year'].dropna().unique().astype(int).tolist())
|
552 |
-
selected_year = st.selectbox("Select Year:", years)
|
553 |
-
|
554 |
-
chart_col, desc_col = st.columns([7, 3])
|
555 |
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
|
|
|
|
|
|
|
|
565 |
|
566 |
with desc_col:
|
567 |
-
st.markdown(
|
568 |
-
|
569 |
-
This
|
570 |
-
|
|
|
|
|
571 |
**Key Features:**
|
572 |
-
* Interactive
|
573 |
-
*
|
574 |
-
|
575 |
-
|
576 |
-
|
|
|
|
|
|
|
577 |
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
578 |
|
579 |
|
580 |
if __name__ == "__main__":
|
|
|
81 |
return fig
|
82 |
|
83 |
def get_top_violations(df, age_group):
|
84 |
+
# Calculate total incidents for the age group
|
85 |
if age_group == 'All Ages':
|
86 |
+
total_incidents = len(df)
|
87 |
+
# Get violations for all ages
|
88 |
violations = pd.concat([
|
89 |
df['Violation1_Drv1'].value_counts(),
|
90 |
df['Violation1_Drv2'].value_counts()
|
91 |
]).groupby(level=0).sum()
|
92 |
else:
|
93 |
+
# Filter for specific age group
|
94 |
filtered_df = df[
|
95 |
(df['Age_Group_Drv1'] == age_group) |
|
96 |
(df['Age_Group_Drv2'] == age_group)
|
97 |
]
|
98 |
+
total_incidents = len(filtered_df)
|
99 |
+
# Get violations for specific age group
|
100 |
violations = pd.concat([
|
101 |
filtered_df['Violation1_Drv1'].value_counts(),
|
102 |
filtered_df['Violation1_Drv2'].value_counts()
|
|
|
105 |
# Convert to DataFrame and format
|
106 |
violations_df = violations.reset_index()
|
107 |
violations_df.columns = ['Violation Type', 'Count']
|
108 |
+
|
109 |
+
# Sort by Count in descending order
|
110 |
+
violations_df = violations_df.sort_values('Count', ascending=False)
|
111 |
+
|
112 |
+
# Calculate percentage of total incidents
|
113 |
+
violations_df['Percentage'] = (violations_df['Count'] / total_incidents * 100).round(2)
|
114 |
violations_df['Percentage'] = violations_df['Percentage'].map('{:.2f}%'.format)
|
115 |
|
116 |
return violations_df.head()
|
|
|
345 |
|
346 |
st.markdown("""
|
347 |
**Team Members:**
|
348 |
+
- Janhavi Tushar Zarapkar ([email protected])
|
349 |
- Hangyue Zhang ([email protected])
|
350 |
- Andrew Nam ([email protected])
|
351 |
- Nirmal Attarde ([email protected])
|
|
|
369 |
df['Weather'] = 'Unknown'
|
370 |
|
371 |
# Create tabs for different visualizations
|
372 |
+
tab1, tab2, tab3, tab4, tab5 = st.tabs([
|
373 |
+
"Crash Trend",
|
374 |
+
"Crash Statistics",
|
375 |
+
"Distribution by Category",
|
376 |
+
"Crash Injuries/Fatalities",
|
377 |
+
"Crash Map"
|
378 |
+
])
|
379 |
|
380 |
with tab1:
|
381 |
+
# Weather condition filter
|
382 |
+
weather = ['All Conditions'] + sorted(df['Weather'].unique())
|
383 |
+
selected_weather = st.selectbox('Select Weather Condition:', weather)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
384 |
|
385 |
+
trend_col, desc_col = st.columns([7, 3])
|
386 |
|
387 |
+
with trend_col:
|
388 |
+
trend_fig = create_crash_trend_chart(df, selected_weather)
|
389 |
+
trend_fig.update_layout(
|
390 |
+
height=800,
|
391 |
+
width=None,
|
392 |
+
margin=dict(l=50, r=50, t=50, b=50)
|
393 |
+
)
|
394 |
+
st.plotly_chart(trend_fig, use_container_width=True)
|
|
|
|
|
|
|
|
|
395 |
|
396 |
with desc_col:
|
397 |
st.markdown("""
|
398 |
+
## **Crash Trend Over Time**
|
399 |
+
This interactive line chart visualizes the trend of unique traffic crashes over the years, optionally filtered by weather conditions. It highlights how crash frequency changes over time, helping identify trends and potential contributing factors.
|
|
|
|
|
400 |
|
401 |
**Key Features:**
|
402 |
+
* **Time Trend Analysis**: Displays the total number of unique crashes for each year, showing long-term patterns.
|
403 |
+
* **Weather Filter**: Users can filter the data by weather conditions (e.g., "Rainy", "Sunny") to analyze how weather impacts crash trends.
|
404 |
+
* **Interactive Tooltips**: Hovering over data points reveals the exact crash count for each year, providing detailed insights.
|
405 |
|
406 |
+
**Color Scheme and Design:**
|
407 |
+
* **Line and Markers**: A smooth line connects data points, with prominent markers for each year to highlight trends clearly.
|
408 |
+
* **Dynamic Title**: The chart updates its title to reflect the selected weather condition or "All Conditions" for the overall trend.
|
409 |
|
410 |
+
**Insights:**
|
411 |
+
This chart helps uncover:
|
412 |
+
* Annual fluctuations in crash incidents.
|
413 |
+
* Correlations between weather conditions and crash frequencies.
|
414 |
+
* Historical patterns that can guide future safety measures and urban planning decisions
|
415 |
""")
|
416 |
+
|
417 |
+
with tab2:
|
418 |
+
# Age group selection
|
419 |
+
age_groups = ['All Ages', '16-25', '26-35', '36-45', '46-55', '56-65', '65+']
|
420 |
+
selected_age = st.selectbox('Select Age Group:', age_groups)
|
421 |
|
422 |
+
chart_col, desc_col = st.columns([7, 3])
|
|
|
|
|
|
|
|
|
423 |
|
424 |
+
with chart_col:
|
425 |
+
# Create and display chart
|
426 |
+
fig = create_severity_violation_chart(df, selected_age)
|
427 |
+
st.plotly_chart(fig, use_container_width=True)
|
428 |
+
|
429 |
+
# Display statistics
|
430 |
+
if selected_age == 'All Ages':
|
431 |
+
total_incidents = len(df)
|
432 |
+
else:
|
433 |
+
total_incidents = len(df[
|
434 |
+
(df['Age_Group_Drv1'] == selected_age) |
|
435 |
+
(df['Age_Group_Drv2'] == selected_age)
|
436 |
+
])
|
437 |
+
|
438 |
+
# Create two columns for statistics
|
439 |
+
col1, col2 = st.columns(2)
|
440 |
+
|
441 |
+
with col1:
|
442 |
+
st.markdown(f"### Total Incidents")
|
443 |
+
st.markdown(f"**{total_incidents:,}** incidents for {selected_age}")
|
444 |
+
|
445 |
+
with col2:
|
446 |
+
st.markdown("### Top Violations")
|
447 |
+
top_violations = get_top_violations(df, selected_age)
|
448 |
+
st.table(top_violations)
|
449 |
|
450 |
+
with desc_col:
|
451 |
+
st.markdown("""
|
452 |
+
## Severity of Violations Across Age Groups
|
453 |
+
|
454 |
+
This section provides an interactive visualization of crash severities linked to specific violation types, segmented by driver age groups. It enables a comprehensive analysis of how age influences crash severity and violation trends.
|
455 |
+
|
456 |
+
**Key Features:**
|
457 |
+
1. **Age Group Analysis**:
|
458 |
+
* Select specific age groups (e.g., "16-25", "65+") or analyze all ages to explore correlations between age, violation type, and crash severity.
|
459 |
+
* Understand how different age groups are involved in various types of violations.
|
460 |
+
|
461 |
+
2. **Violation Breakdown**:
|
462 |
+
* Examine the most frequent violations contributing to traffic accidents for each age group.
|
463 |
+
* View detailed statistics showing the distribution of violation types.
|
464 |
+
|
465 |
+
**Insights:**
|
466 |
+
* Identifies high-risk behaviors within specific age groups, such as reckless driving in younger drivers or impaired driving in older groups.
|
467 |
+
* Highlights which violations are associated with more severe outcomes, aiding targeted safety interventions and public awareness campaigns.
|
468 |
+
* Supports data-driven decision making for age-specific traffic safety programs.
|
469 |
+
""")
|
470 |
+
|
471 |
+
with tab3:
|
472 |
+
# Dropdown for category selection
|
473 |
+
categories = [
|
474 |
+
'Collisionmanner',
|
475 |
+
'Lightcondition',
|
476 |
+
'Weather',
|
477 |
+
'SurfaceCondition',
|
478 |
+
'AlcoholUse_Drv1',
|
479 |
+
'Gender_Drv1',
|
480 |
+
]
|
481 |
+
selected_category = st.selectbox("Select Category:", categories)
|
482 |
+
|
483 |
+
# Dropdown for year selection
|
484 |
+
years = ['All Years'] + sorted(df['Year'].dropna().unique().astype(int).tolist())
|
485 |
+
selected_year = st.selectbox("Select Year:", years)
|
486 |
+
|
487 |
+
chart_col, desc_col = st.columns([7, 3])
|
488 |
|
489 |
+
with chart_col:
|
490 |
+
distribution_chart = create_category_distribution_chart(df, selected_category, selected_year)
|
491 |
+
distribution_chart.update_layout(
|
492 |
+
height=800,
|
493 |
+
width=None,
|
|
|
494 |
margin=dict(l=50, r=50, t=50, b=50)
|
495 |
)
|
496 |
+
st.plotly_chart(distribution_chart, use_container_width=True)
|
497 |
|
498 |
with desc_col:
|
499 |
+
st.markdown(f"""
|
500 |
+
## Distribution of Incidents by {selected_category}
|
501 |
+
This visualization explores the distribution of traffic incidents across various categories, such as Collision Manner, Weather, Surface Condition, Alcohol Use, and Driver Gender. Each bar represents a specific category value (e.g., "Male" or "Female" for Gender), and the bars are divided into segments based on Injury Severity (e.g., Minor, Moderate, Serious, Fatal).
|
502 |
+
|
503 |
+
**Key features include:**
|
504 |
+
* Interactive Filters: Select a category and filter by year to analyze trends over time.
|
505 |
+
* Insightful Tooltips: Hover over each segment to view the exact count and percentage of incidents for a given severity level.
|
506 |
+
* Comparative Analysis: Quickly identify how different conditions or behaviors correlate with injury severity.
|
507 |
+
|
508 |
+
This chart provides actionable insights into factors contributing to traffic incidents and their outcomes, helping stakeholders target interventions and improve road safety.
|
509 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
510 |
|
511 |
with tab4:
|
512 |
# Dropdown for Unit Type selection
|
|
|
518 |
unit_type_pairs = sorted(list(unit_type_pairs))
|
519 |
unit_type = st.selectbox("Select Unit Type Pair", options=['Total'] + unit_type_pairs)
|
520 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
521 |
chart_col, desc_col = st.columns([7, 3])
|
522 |
|
523 |
with chart_col:
|
|
|
524 |
injuries_fatalities_chart = create_injuries_fatalities_chart(df, unit_type)
|
525 |
injuries_fatalities_chart = injuries_fatalities_chart.properties(
|
526 |
+
height=800
|
527 |
)
|
528 |
st.altair_chart(injuries_fatalities_chart, use_container_width=True)
|
529 |
|
|
|
557 |
|
558 |
This visualization aids stakeholders in developing effective safety measures and resource allocation strategies throughout the year.
|
559 |
""")
|
560 |
+
|
|
|
|
|
561 |
with tab5:
|
562 |
+
years = sorted(df['Year'].unique())
|
563 |
+
selected_year = st.selectbox('Select Year:', years)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
564 |
|
565 |
+
map_col, desc_col = st.columns([7, 3])
|
566 |
+
|
567 |
+
with map_col:
|
568 |
+
map_placeholder = st.empty()
|
569 |
+
with map_placeholder:
|
570 |
+
m = create_map(df, selected_year)
|
571 |
+
map_data = st_folium(
|
572 |
+
m,
|
573 |
+
width=None,
|
574 |
+
height=800,
|
575 |
+
key=f"map_{selected_year}",
|
576 |
+
returned_objects=["null_drawing"]
|
577 |
+
)
|
578 |
|
579 |
with desc_col:
|
580 |
+
st.markdown("""
|
581 |
+
### Traffic Crash Location Map
|
582 |
+
This interactive map visualizes traffic accidents in Tempe for the selected year. It combines **marker clustering** and a **heatmap** to show:
|
583 |
+
1. **Accident Markers**: Red markers indicate individual accidents, with popups displaying the coordinates, date/time, and severity of each incident.
|
584 |
+
2. **Heatmap**: The heatmap highlights accident hotspots with colors ranging from blue (low frequency) to yellow (moderate) and red (high frequency), showing areas with more frequent accidents.
|
585 |
+
|
586 |
**Key Features:**
|
587 |
+
* **Interactive Year Selection**: Users can select a year to view accidents for that specific time.
|
588 |
+
* **Accident Patterns**: The map reveals accident-prone areas and severity patterns, helping identify dangerous locations.
|
589 |
+
|
590 |
+
**Color Scheme:**
|
591 |
+
* **Red**: Individual accident markers.
|
592 |
+
* **Blue to Red**: Heatmap colors indicate accident frequency, from low (blue) to high (red).
|
593 |
+
|
594 |
+
This map provides insights into accident trends and can help guide safety improvements in the city.
|
595 |
""")
|
596 |
+
|
597 |
+
st.markdown("---")
|
598 |
+
|
599 |
+
# Add TODO section title
|
600 |
+
st.markdown("## To-Do List for Part 3")
|
601 |
+
st.markdown("For the final project part 3, we plan to create two pairs of linked interactive visualizations for analyzing traffic accident data as follows:")
|
602 |
+
|
603 |
+
# Create two columns
|
604 |
+
plan_col, deliver_col = st.columns(2)
|
605 |
+
|
606 |
+
with plan_col:
|
607 |
+
st.markdown("""
|
608 |
+
### Planned Visualizations
|
609 |
+
|
610 |
+
1. **Severity-Location Analysis**
|
611 |
+
* A bar chart displaying accident severity counts
|
612 |
+
* A map visualizing accident locations with marker clusters and heatmaps
|
613 |
+
* Interactions in one visualization (e.g., clicking a bar in the chart) will dynamically update the other
|
614 |
+
* Enables seamless exploration of data
|
615 |
+
|
616 |
+
2. **Violation-Severity Analysis**
|
617 |
+
* An interactive bar and pie chart system
|
618 |
+
* Shows the distribution of severity levels for selected violation types
|
619 |
+
* Clicking a specific bar from the "Crash Severity Distribution by Violation Type" bar plot
|
620 |
+
* Dynamically updates a pie plot showing detailed distribution of the chosen violation type
|
621 |
+
* Based on the selected age group
|
622 |
+
""")
|
623 |
+
|
624 |
+
with deliver_col:
|
625 |
+
st.markdown("""
|
626 |
+
### Key Deliverables
|
627 |
+
|
628 |
+
* **Interactive Bar Chart**
|
629 |
+
- Displays accident counts by severity
|
630 |
+
- Allows users to filter data by clicking specific bars
|
631 |
+
|
632 |
+
* **Interactive Map**
|
633 |
+
- Shows accident locations using marker clusters and heatmaps
|
634 |
+
- Features popups displaying details (e.g., date, severity)
|
635 |
+
|
636 |
+
* **Two-Way Interactivity**
|
637 |
+
- Synchronizes updates between the bar chart and map
|
638 |
+
- Based on user interactions
|
639 |
+
|
640 |
+
* **User Interface**
|
641 |
+
- Sidebar controls for year selection
|
642 |
+
- Clear interaction instructions
|
643 |
+
- Display of applied filters
|
644 |
+
""")
|
645 |
+
|
646 |
|
647 |
|
648 |
if __name__ == "__main__":
|