Commit ·
61dfc55
1
Parent(s): 523ca1c
Update project to Part 3 and enhance EV dashboard (visualization).
Browse filesRenamed project reference from Part 2 to Part 3 across various files. Updated the dashboard in `app.py` to streamline the presentation and enhance interactivity with new visualizations and a focus on exploring electric vehicle trends. The improved narrative now provides deeper insights into EV adoption in Washington State.
- .idea/IS_445_Final_Project_Part2.iml +1 -1
- .idea/misc.xml +1 -1
- README.md +1 -1
- app.py +75 -122
- pyproject.toml +1 -1
.idea/IS_445_Final_Project_Part2.iml
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
| 4 |
<exclude-output />
|
| 5 |
<content url="file://$MODULE_DIR$" />
|
| 6 |
-
<orderEntry type="
|
| 7 |
<orderEntry type="sourceFolder" forTests="false" />
|
| 8 |
</component>
|
| 9 |
</module>
|
|
|
|
| 3 |
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
| 4 |
<exclude-output />
|
| 5 |
<content url="file://$MODULE_DIR$" />
|
| 6 |
+
<orderEntry type="jdk" jdkName="Poetry (Final_Project_Part3)" jdkType="Python SDK" />
|
| 7 |
<orderEntry type="sourceFolder" forTests="false" />
|
| 8 |
</component>
|
| 9 |
</module>
|
.idea/misc.xml
CHANGED
|
@@ -4,7 +4,7 @@
|
|
| 4 |
<option name="sdkName" value="Python 3.13 (final-project-part2-u8uBTYck-py3.13)" />
|
| 5 |
</component>
|
| 6 |
<component name="GOROOT" url="file:///opt/homebrew/opt/go/libexec" />
|
| 7 |
-
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="
|
| 8 |
<output url="file://$PROJECT_DIR$/out" />
|
| 9 |
</component>
|
| 10 |
</project>
|
|
|
|
| 4 |
<option name="sdkName" value="Python 3.13 (final-project-part2-u8uBTYck-py3.13)" />
|
| 5 |
</component>
|
| 6 |
<component name="GOROOT" url="file:///opt/homebrew/opt/go/libexec" />
|
| 7 |
+
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Poetry (Final_Project_Part3)" project-jdk-type="Python SDK">
|
| 8 |
<output url="file://$PROJECT_DIR$/out" />
|
| 9 |
</component>
|
| 10 |
</project>
|
README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
---
|
| 2 |
-
title: Group 5 Final Project - Part
|
| 3 |
emoji: 🏢
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: gray
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Group 5 Final Project - Part 3
|
| 3 |
emoji: 🏢
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: gray
|
app.py
CHANGED
|
@@ -1,140 +1,83 @@
|
|
|
|
|
| 1 |
import pandas as pd
|
| 2 |
import plotly.express as px
|
| 3 |
import pydeck as pdk
|
| 4 |
-
import streamlit as st
|
| 5 |
-
from streamlit_plotly_events import plotly_events
|
| 6 |
-
|
| 7 |
-
# Group 5 Final Project - Part 2 Dashboard
|
| 8 |
-
# Group Members: Nabeel Bashir, Tony An, Devansh Kumar, Jiajun Li
|
| 9 |
-
|
| 10 |
-
# Streamlit application setup
|
| 11 |
-
st.title('Group 5 Final Project - Part 2 (Dashboard)')
|
| 12 |
-
st.text("Group Members: Nabeel Bashir, Tony An, Devansh Kumar, Jiajun Li")
|
| 13 |
-
|
| 14 |
-
# Project URL
|
| 15 |
-
st.text("The URL for this app is: https://huggingface.co/spaces/fa24-is445-group5/Final_Project_Part2")
|
| 16 |
-
|
| 17 |
-
# Load the electric vehicle dataset
|
| 18 |
-
ev_data = pd.read_csv('data/Electric_Vehicle_Population_Data.csv')
|
| 19 |
|
| 20 |
-
#
|
| 21 |
-
st.title(
|
| 22 |
-
st.markdown(
|
| 23 |
-
This dashboard helps experts and stakeholders understand the distribution and characteristics of electric vehicles
|
| 24 |
-
in various counties and cities.''')
|
| 25 |
|
| 26 |
-
#
|
| 27 |
-
|
| 28 |
-
|
| 29 |
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
All charts are interactive. You can click on bars to highlight corresponding data points in other charts, making it easier to discover patterns and relationships.
|
| 33 |
-
|
| 34 |
-
The map is also interactive; you can zoom in, rotate, and click on points to see additional information about each vehicle.''')
|
| 35 |
-
|
| 36 |
-
# Extract latitude and longitude from 'Vehicle Location' column
|
| 37 |
ev_data[['Longitude', 'Latitude']] = ev_data['Vehicle Location'].str.extract(r'POINT \((-?\d+\.\d+) (-?\d+\.\d+)\)')
|
| 38 |
ev_data['Latitude'] = pd.to_numeric(ev_data['Latitude'], errors='coerce')
|
| 39 |
ev_data['Longitude'] = pd.to_numeric(ev_data['Longitude'], errors='coerce')
|
| 40 |
|
| 41 |
-
#
|
| 42 |
-
|
| 43 |
-
|
| 44 |
|
| 45 |
-
|
| 46 |
-
selected_make = st.sidebar.multiselect('Select Make', make_list, default=make_list)
|
| 47 |
|
| 48 |
-
#
|
| 49 |
-
|
| 50 |
|
| 51 |
-
#
|
| 52 |
-
|
| 53 |
-
|
|
|
|
| 54 |
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
make_counts = filtered_data['Make'].value_counts().reset_index()
|
| 58 |
-
make_counts.columns = ['Make', 'Count']
|
| 59 |
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
color_map = 'green'
|
| 69 |
-
|
| 70 |
-
# Create a bar chart showing vehicle count by make
|
| 71 |
-
chart = px.bar(
|
| 72 |
-
make_counts,
|
| 73 |
-
x='Make',
|
| 74 |
-
y='Count',
|
| 75 |
-
title="Vehicle Count by Make",
|
| 76 |
-
labels={'Make': 'Vehicle Make', 'Count': 'Number of Vehicles'},
|
| 77 |
-
color='Make',
|
| 78 |
-
color_discrete_map=color_map if isinstance(color_map, dict) else None
|
| 79 |
-
)
|
| 80 |
-
chart.update_layout(clickmode='event+select') # Enable click interactions
|
| 81 |
-
return chart
|
| 82 |
-
|
| 83 |
-
# Display the bar chart and capture click data
|
| 84 |
-
bar_chart = create_bar_chart(st.session_state.get('selected_make', None))
|
| 85 |
-
clicked_points = plotly_events(bar_chart, click_event=True, hover_event=False, select_event=False)
|
| 86 |
-
|
| 87 |
-
# Update the selected make based on user interaction
|
| 88 |
-
if clicked_points:
|
| 89 |
-
st.session_state['selected_make'] = clicked_points[0]['x'] # Get clicked make
|
| 90 |
-
else:
|
| 91 |
-
st.session_state['selected_make'] = None
|
| 92 |
-
|
| 93 |
-
# Display selected make
|
| 94 |
-
selected_make = st.session_state['selected_make']
|
| 95 |
-
if selected_make:
|
| 96 |
-
st.write(f"Selected Make: {selected_make}")
|
| 97 |
-
|
| 98 |
-
# Filter data for the line chart based on selected make
|
| 99 |
-
if selected_make:
|
| 100 |
-
filtered_data = ev_data[ev_data['Make'] == selected_make]
|
| 101 |
-
else:
|
| 102 |
-
filtered_data = ev_data
|
| 103 |
-
|
| 104 |
-
# Group data by model year for the filtered data
|
| 105 |
-
model_year_data = filtered_data.groupby('Model Year').size().reset_index(name='Count')
|
| 106 |
-
|
| 107 |
-
# Create the line chart for model count by year
|
| 108 |
-
st.subheader(f"Number of Vehicles by Model Year for {selected_make if selected_make else 'All Makes'}")
|
| 109 |
-
line_chart = px.line(
|
| 110 |
-
model_year_data,
|
| 111 |
-
x='Model Year',
|
| 112 |
y='Count',
|
| 113 |
-
title=
|
| 114 |
-
labels={
|
| 115 |
-
|
| 116 |
)
|
|
|
|
| 117 |
|
| 118 |
-
#
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
-
#
|
|
|
|
|
|
|
| 127 |
st.pydeck_chart(pdk.Deck(
|
| 128 |
initial_view_state=pdk.ViewState(
|
| 129 |
-
latitude=filtered_data['
|
| 130 |
-
longitude=filtered_data['
|
| 131 |
-
zoom=
|
| 132 |
),
|
| 133 |
layers=[
|
| 134 |
pdk.Layer(
|
| 135 |
'ScatterplotLayer',
|
| 136 |
data=filtered_data,
|
| 137 |
-
get_position='[
|
| 138 |
get_radius=200,
|
| 139 |
get_color='[200, 30, 0, 160]',
|
| 140 |
pickable=True
|
|
@@ -142,19 +85,29 @@ st.pydeck_chart(pdk.Deck(
|
|
| 142 |
],
|
| 143 |
tooltip={
|
| 144 |
"html": "<b>Make:</b> {Make}<br/><b>Model:</b> {Model}<br/><b>Electric Range:</b> {Electric Range}",
|
| 145 |
-
"style": {
|
| 146 |
-
"backgroundColor": "steelblue",
|
| 147 |
-
"color": "white"
|
| 148 |
-
}
|
| 149 |
}
|
| 150 |
))
|
| 151 |
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
This dataset is uploaded huggingface repo using Git LFS, so there is no need to revise the plan for hosting this data.''')
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
import pandas as pd
|
| 3 |
import plotly.express as px
|
| 4 |
import pydeck as pdk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
+
# Group Members
|
| 7 |
+
st.title("Driving the Future: Exploring Electric Vehicle Trends")
|
| 8 |
+
st.markdown("### Authors: Tony An, Nabeel Bashir, Devansh Kumar, Jiajun Li")
|
|
|
|
|
|
|
| 9 |
|
| 10 |
+
# Load Data
|
| 11 |
+
data_path = 'data/Electric_Vehicle_Population_Data.csv'
|
| 12 |
+
ev_data = pd.read_csv(data_path)
|
| 13 |
|
| 14 |
+
# Data Preparation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
ev_data[['Longitude', 'Latitude']] = ev_data['Vehicle Location'].str.extract(r'POINT \((-?\d+\.\d+) (-?\d+\.\d+)\)')
|
| 16 |
ev_data['Latitude'] = pd.to_numeric(ev_data['Latitude'], errors='coerce')
|
| 17 |
ev_data['Longitude'] = pd.to_numeric(ev_data['Longitude'], errors='coerce')
|
| 18 |
|
| 19 |
+
# Write-up
|
| 20 |
+
st.markdown("""
|
| 21 |
+
Electric vehicles (EVs) represent a transformative shift in the transportation sector, combining technological innovation with environmental responsibility.
|
| 22 |
|
| 23 |
+
Through this interactive article, we aim to uncover key trends in EV adoption, including the growing number of electric vehicles across counties in Washington State, the release patterns of EV models over the years, and the geographic distribution of EVs. By examining these trends, we can provide insights into the factors driving EV adoption and their implications for infrastructure and policy.
|
|
|
|
| 24 |
|
| 25 |
+
### Why Focus on Washington State?
|
| 26 |
+
Washington State has emerged as a leader in promoting clean energy initiatives and adopting electric vehicles. With a robust network of charging stations and incentives for EV buyers, the state provides a rich dataset to analyze the adoption trends of electric vehicles. By focusing on a single state, we can gain deeper insights into localized patterns and challenges, which can be used to inform similar efforts in other regions.
|
| 27 |
|
| 28 |
+
### What You'll Discover
|
| 29 |
+
- The distribution and characteristics of EVs across counties in Washington State.
|
| 30 |
+
- The timeline of EV model releases.
|
| 31 |
+
- Insights into infrastructure, including potential charging station locations.
|
| 32 |
|
| 33 |
+
This analysis focuses on Washington State to provide a localized perspective and highlight trends at a manageable scale.
|
| 34 |
+
""")
|
|
|
|
|
|
|
| 35 |
|
| 36 |
+
# Central Interactive Visualization
|
| 37 |
+
st.subheader("Explore EV Distribution by County")
|
| 38 |
+
county_counts = ev_data['County'].value_counts().reset_index()
|
| 39 |
+
county_counts.columns = ['County', 'Count']
|
| 40 |
+
|
| 41 |
+
fig_county = px.bar(
|
| 42 |
+
county_counts,
|
| 43 |
+
x='County',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
y='Count',
|
| 45 |
+
title="Electric Vehicle Counts by County",
|
| 46 |
+
labels={"Count": "Number of EVs", "County": "County"},
|
| 47 |
+
height=500
|
| 48 |
)
|
| 49 |
+
st.plotly_chart(fig_county, use_container_width=True)
|
| 50 |
|
| 51 |
+
# Contextual Visualization 1: Vehicle Model Trends
|
| 52 |
+
ev_data['Model Year'] = pd.to_numeric(ev_data['Model Year'], errors='coerce')
|
| 53 |
+
model_year_counts = ev_data['Model Year'].value_counts().reset_index()
|
| 54 |
+
model_year_counts.columns = ['Year', 'Count']
|
| 55 |
+
model_year_counts = model_year_counts.sort_values('Year')
|
| 56 |
|
| 57 |
+
fig_year = px.line(
|
| 58 |
+
model_year_counts,
|
| 59 |
+
x='Year',
|
| 60 |
+
y='Count',
|
| 61 |
+
title="Trend of EV Models Released Over Time",
|
| 62 |
+
labels={"Year": "Model Year", "Count": "Number of Models"},
|
| 63 |
+
markers=True
|
| 64 |
+
)
|
| 65 |
+
st.plotly_chart(fig_year, use_container_width=True)
|
| 66 |
|
| 67 |
+
# Contextual Visualization 2: Map of EV Locations
|
| 68 |
+
st.subheader("Geographic Distribution of EVs")
|
| 69 |
+
filtered_data = ev_data.dropna(subset=['Latitude', 'Longitude'])
|
| 70 |
st.pydeck_chart(pdk.Deck(
|
| 71 |
initial_view_state=pdk.ViewState(
|
| 72 |
+
latitude=filtered_data['Latitude'].mean(),
|
| 73 |
+
longitude=filtered_data['Longitude'].mean(),
|
| 74 |
+
zoom=7,
|
| 75 |
),
|
| 76 |
layers=[
|
| 77 |
pdk.Layer(
|
| 78 |
'ScatterplotLayer',
|
| 79 |
data=filtered_data,
|
| 80 |
+
get_position='[Longitude, Latitude]',
|
| 81 |
get_radius=200,
|
| 82 |
get_color='[200, 30, 0, 160]',
|
| 83 |
pickable=True
|
|
|
|
| 85 |
],
|
| 86 |
tooltip={
|
| 87 |
"html": "<b>Make:</b> {Make}<br/><b>Model:</b> {Model}<br/><b>Electric Range:</b> {Electric Range}",
|
| 88 |
+
"style": {"backgroundColor": "steelblue", "color": "white"}
|
|
|
|
|
|
|
|
|
|
| 89 |
}
|
| 90 |
))
|
| 91 |
|
| 92 |
+
st.markdown("""
|
| 93 |
+
### Analysis and Key Takeaways
|
| 94 |
+
|
| 95 |
+
1. **County-Level Distribution**: King County stands out as the hub for electric vehicles in Washington State, accounting for the vast majority of EVs. This concentration aligns with the county's urban population density and robust infrastructure supporting EVs.
|
| 96 |
+
|
| 97 |
+
2. **Model Release Trends**: The timeline of EV model releases shows a significant surge in recent years, reflecting advancements in EV technology and increasing consumer demand. The spike in 2020-2021 likely corresponds to policy incentives and a growing focus on reducing carbon emissions.
|
| 98 |
+
|
| 99 |
+
3. **Geographic Insights**: The geographic visualization highlights key clusters of EV adoption, primarily around metropolitan areas. These clusters underline the importance of accessible charging stations and supportive local policies in driving EV adoption.
|
| 100 |
+
|
| 101 |
+
### Moving Forward
|
| 102 |
+
As EV adoption continues to grow, insights from localized data like this can inform infrastructure planning and policy-making. Expanding charging networks, incentivizing adoption in underserved areas, and addressing technological barriers are crucial steps for achieving widespread EV integration.
|
| 103 |
+
|
| 104 |
+
""")
|
| 105 |
+
|
| 106 |
+
# Citations and Dataset Links
|
| 107 |
+
st.markdown("""
|
| 108 |
+
### Sources
|
| 109 |
+
1. Dataset: [Electric Vehicle Population Data](https://catalog.data.gov/dataset/electric-vehicle-population-data)
|
| 110 |
+
2. Additional Visualization Inspiration: [US Department of Energy EV Statistics](https://afdc.energy.gov/data)
|
| 111 |
|
| 112 |
+
All visualizations and data preparation were created by the authors, datasets found online.
|
| 113 |
+
""")
|
|
|
pyproject.toml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
[tool.poetry]
|
| 2 |
-
name = "
|
| 3 |
version = "0.1.0"
|
| 4 |
description = ""
|
| 5 |
authors = ["Tony An <anxuanzi@gmail.com>"]
|
|
|
|
| 1 |
[tool.poetry]
|
| 2 |
+
name = "Final_Project_Part3"
|
| 3 |
version = "0.1.0"
|
| 4 |
description = ""
|
| 5 |
authors = ["Tony An <anxuanzi@gmail.com>"]
|