import streamlit as st
import pandas as pd
import folium
from folium.plugins import MarkerCluster, HeatMap
from streamlit_plotly_events import plotly_events
import plotly.express as px
# Function to create the map
@st.cache_data
def create_map(df, selected_year, selected_severity=None):
# Filter data by selected year
filtered_df = df[df['Year'] == selected_year]
# Filter further by selected severity if provided
if selected_severity:
filtered_df = filtered_df[filtered_df['Injuryseverity'] == selected_severity]
# Remove rows with missing latitude or longitude
filtered_df = filtered_df.dropna(subset=['Latitude', 'Longitude'])
# Create the map
m = folium.Map(
location=[33.4255, -111.9400], # Default location (can be customized)
zoom_start=12,
control_scale=True,
tiles='CartoDB positron'
)
# Add marker cluster
marker_cluster = MarkerCluster(name="Accident Locations").add_to(m)
# Add accident markers
for _, row in filtered_df.iterrows():
folium.Marker(
location=[row['Latitude'], row['Longitude']],
popup=f"Accident at {row['Longitude']}, {row['Latitude']}
Date: {row['DateTime']}
Severity: {row['Injuryseverity']}",
icon=folium.Icon(color='red')
).add_to(marker_cluster)
# Add heatmap
heat_data = filtered_df[['Latitude', 'Longitude']].values.tolist()
HeatMap(heat_data, radius=15, max_zoom=13, min_opacity=0.3, name="Heat Map").add_to(m)
folium.LayerControl().add_to(m)
return m
# Function to create a bar chart based on accident severity
def create_bar_chart(df, selected_year):
filtered_df = df[df['Year'] == selected_year]
severity_count = filtered_df['Injuryseverity'].value_counts().reset_index()
severity_count.columns = ['Injuryseverity', 'Count']
fig = px.bar(
severity_count,
x='Injuryseverity',
y='Count',
title="Accidents by Severity",
labels={'Injuryseverity': 'Severity', 'Count': 'Number of Accidents'}
)
fig.update_traces(marker_color='blue')
fig.update_layout(clickmode='event+select') # Enable interactivity
return fig
# Streamlit app
def app():
# Load your dataset here
df = pd.read_csv("Crash_Data_Report.csv") # Replace with your actual dataset
# Sidebar for selection
st.sidebar.header("Select Filters")
selected_year = st.sidebar.selectbox("Select Year", df['Year'].unique())
# Initialize session state for selected severity
if "selected_severity" not in st.session_state:
st.session_state["selected_severity"] = None
# Bar Chart visualization
st.subheader("Accidents by Severity")
bar_chart = create_bar_chart(df, selected_year)
# Capture user interaction
selected_points = plotly_events(bar_chart, click_event=True, hover_event=False)
if selected_points:
# Get the selected severity from the clicked bar
selected_severity = selected_points[0]['x']
st.session_state["selected_severity"] = selected_severity
else:
selected_severity = st.session_state["selected_severity"]
# Map visualization
st.subheader("Accidents Map")
map_obj = create_map(df, selected_year, selected_severity)
st.components.v1.html(map_obj._repr_html_(), height=600)
# Display current filter
st.sidebar.write(f"Selected Severity: {selected_severity if selected_severity else 'All'}")
# Run the Streamlit app
if __name__ == "__main__":
app()