hyzhang00 commited on
Commit
a76acf8
·
verified ·
1 Parent(s): df1ef3c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +212 -144
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
- violations_df['Percentage'] = (violations_df['Count'] / violations_df['Count'].sum() * 100).round(2)
 
 
 
 
 
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 [email protected]
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(["Crash Statistics", "Crash Map", "Crash Trend", "Crash Injuries/Fatalities","Distribution by Category"])
 
 
 
 
 
 
362
 
363
  with tab1:
364
- # Age group selection
365
- age_groups = ['All Ages', '16-25', '26-35', '36-45', '46-55', '56-65', '65+']
366
- selected_age = st.selectbox('Select Age Group:', age_groups)
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
- map_col, desc_col = st.columns([7, 3])
399
 
400
- with map_col:
401
- # Create and display map
402
- map_placeholder = st.empty()
403
- with map_placeholder:
404
- m = create_map(df, selected_year)
405
- map_data = st_folium(
406
- m,
407
- width=None,
408
- height=800,
409
- key=f"map_{selected_year}",
410
- returned_objects=["null_drawing"]
411
- )
412
 
413
  with desc_col:
414
  st.markdown("""
415
- ### Traffic Crash Location Map
416
- This interactive map visualizes traffic accidents in Tempe for the selected year. It combines **marker clustering** and a **heatmap** to show:
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
- * **Interactive Year Selection**: Users can select a year to view accidents for that specific time.
422
- * **Accident Patterns**: The map reveals accident-prone areas and severity patterns, helping identify dangerous locations.
 
423
 
424
- **Color Scheme:**
425
- * **Red**: Individual accident markers.
426
- * **Blue to Red**: Heatmap colors indicate accident frequency, from low (blue) to high (red).
427
 
428
- This map provides insights into accident trends and can help guide safety improvements in the city.
 
 
 
 
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
- # Create and display line graph
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
 
439
- trend_col, desc_col = st.columns([7, 3])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
 
441
- with trend_col:
442
- trend_fig = create_crash_trend_chart(df, selected_weather)
443
- # Update the figure layout for larger size
444
- trend_fig.update_layout(
445
- height=800, # Increased height
446
- width=None, # Let width be responsive
447
  margin=dict(l=50, r=50, t=50, b=50)
448
  )
449
- st.plotly_chart(trend_fig, use_container_width=True)
450
 
451
  with desc_col:
452
- st.markdown("""
453
- ## **Crash Trend Over Time**
454
- 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.
455
-
456
- **Key Features:**
457
- * **Time Trend Analysis**: Displays the total number of unique crashes for each year, showing long-term patterns.
458
- * **Weather Filter**: Users can filter the data by weather conditions (e.g., "Rainy", "Sunny") to analyze how weather impacts crash trends.
459
- * **Interactive Tooltips**: Hovering over data points reveals the exact crash count for each year, providing detailed insights.
460
- **Color Scheme and Design:**
461
- * **Line and Markers**: A smooth line connects data points, with prominent markers for each year to highlight trends clearly.
462
- * **Dynamic Title**: The chart updates its title to reflect the selected weather condition or "All Conditions" for the overall trend.
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 # Make the chart taller to match the description column
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
- # Dropdown for category selection
540
- categories = [
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
- with chart_col:
557
- distribution_chart = create_category_distribution_chart(df, selected_category, selected_year)
558
- # Update the figure layout for larger size
559
- distribution_chart.update_layout(
560
- height=800, # Increased height
561
- width=None, # Let width be responsive
562
- margin=dict(l=50, r=50, t=50, b=50)
563
- )
564
- st.plotly_chart(distribution_chart, use_container_width=True)
 
 
 
 
565
 
566
  with desc_col:
567
- st.markdown(f"""
568
- ## Distribution of Incidents by {selected_category}
569
- 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).
570
-
 
 
571
  **Key Features:**
572
- * Interactive Filters: Select a category and filter by year to analyze trends over time.
573
- * Insightful Tooltips: Hover over each segment to view the exact count and percentage of incidents for a given severity level.
574
- * Comparative Analysis: Quickly identify how different conditions or behaviors correlate with injury severity.
575
-
576
- This chart provides actionable insights into factors contributing to traffic incidents and their outcomes, helping stakeholders target interventions and improve road safety.
 
 
 
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__":