FantasticTony commited on
Commit
61dfc55
·
1 Parent(s): 523ca1c

Update project to Part 3 and enhance EV dashboard (visualization).

Browse files

Renamed 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.

Files changed (5) hide show
  1. .idea/IS_445_Final_Project_Part2.iml +1 -1
  2. .idea/misc.xml +1 -1
  3. README.md +1 -1
  4. app.py +75 -122
  5. 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="inheritedJdk" />
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="Python 3.13 (final-project-part2-u8uBTYck-py3.13)" project-jdk-type="Python SDK">
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 2
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
- # Dashboard introduction
21
- st.title('Electric Vehicle Population Data Dashboard')
22
- st.markdown('''Explore the electric vehicle data interactively using this dashboard.
23
- This dashboard helps experts and stakeholders understand the distribution and characteristics of electric vehicles
24
- in various counties and cities.''')
25
 
26
- # Dashboard usage explanation
27
- st.markdown('''### How to Use This Dashboard
28
- To explore the dataset, use the global filter options in the sidebar to filter by county and make. These filters will update all the visualizations, providing a focused view of the data.
29
 
30
- Alternatively, you can select a specific vehicle make directly in the "Vehicle Count by Make" chart. This selection will link to and update the rest of the visualizations to display data relevant to the selected make.
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
- # Sidebar filter options
42
- county_list = ev_data['County'].unique()
43
- make_list = ev_data['Make'].unique()
44
 
45
- selected_county = st.sidebar.selectbox('Select County', county_list)
46
- selected_make = st.sidebar.multiselect('Select Make', make_list, default=make_list)
47
 
48
- # Filter data based on sidebar selections
49
- filtered_data = ev_data[(ev_data['County'] == selected_county) & (ev_data['Make'].isin(selected_make))]
50
 
51
- # Display filtered data
52
- st.subheader('Filtered Data')
53
- st.write(filtered_data)
 
54
 
55
- # Interactive Bar Chart - Vehicle Count by Make
56
- st.subheader('Vehicle Count by Make')
57
- make_counts = filtered_data['Make'].value_counts().reset_index()
58
- make_counts.columns = ['Make', 'Count']
59
 
60
- def create_bar_chart(selected_make=None):
61
- # If a make is selected, highlight it in blue, otherwise default to green
62
- if selected_make:
63
- make_counts['Color'] = make_counts['Make'].apply(
64
- lambda x: 'blue' if x == selected_make else 'green'
65
- )
66
- color_map = make_counts.set_index('Make')['Color']
67
- else:
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=f"Number of Vehicles by Model Year for {selected_make if selected_make else 'All Makes'}",
114
- labels={'Model Year': 'Year', 'Count': 'Number of Vehicles'},
115
- markers=True
116
  )
 
117
 
118
- # Display the line chart
119
- st.plotly_chart(line_chart, use_container_width=True)
 
 
 
120
 
121
- # Interactive Map of Vehicle Locations
122
- st.subheader('Map of Vehicle Locations')
123
- filtered_data = filtered_data.dropna(subset=['Latitude', 'Longitude'])
124
- filtered_data.rename(columns={'Latitude': 'latitude', 'Longitude': 'longitude'}, inplace=True)
 
 
 
 
 
125
 
126
- # Create an interactive map using PyDeck
 
 
127
  st.pydeck_chart(pdk.Deck(
128
  initial_view_state=pdk.ViewState(
129
- latitude=filtered_data['latitude'].mean(),
130
- longitude=filtered_data['longitude'].mean(),
131
- zoom=10,
132
  ),
133
  layers=[
134
  pdk.Layer(
135
  'ScatterplotLayer',
136
  data=filtered_data,
137
- get_position='[longitude, latitude]',
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
- # Contextual datasets
153
- st.markdown('''### Contextual Datasets
154
- A potentially useful contextual dataset could be the [Electric Charging Stations Locations](https://afdc.energy.gov/fuels/electricity_locations.html).
155
- This dataset will provide information about the availability of charging stations in each county, allowing for a deeper
156
- analysis of the convenience and accessibility of electric vehicles in different regions.''')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
- # Dataset size comment
159
- st.markdown('''### Dataset Size
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 = "Final_Project_Part2"
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>"]