File size: 6,509 Bytes
979f8ec
4830705
5dd9543
979f8ec
4830705
979f8ec
4830705
 
 
 
d16d6dd
 
 
4830705
d16d6dd
 
4830705
d16d6dd
3ddfd7a
4830705
d16d6dd
 
 
 
64d50ce
4830705
290ce05
4830705
 
 
290ce05
 
 
 
 
4830705
 
 
 
 
 
d16d6dd
 
3ddfd7a
d16d6dd
 
979f8ec
4830705
d16d6dd
979f8ec
4830705
d16d6dd
 
 
4830705
 
 
 
d16d6dd
4830705
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d16d6dd
 
 
5dd9543
4830705
5dd9543
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4830705
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import pandas as pd
import plotly.express as px
import pydeck as pdk
import streamlit as st
from streamlit_plotly_events import plotly_events

# Group 5 Final Project - Part 2 Dashboard
# Group Members: Nabeel Bashir, Tony An, Devansh Kumar, Jiajun Li

# Streamlit application setup
st.title('Group 5 Final Project - Part 2 (Dashboard)')
st.text("Group Members: Nabeel Bashir, Tony An, Devansh Kumar, Jiajun Li")

# Project URL
st.text("The URL for this app is: https://huggingface.co/spaces/fa24-is445-group5/Final_Project_Part2")

# Load the electric vehicle dataset
ev_data = pd.read_csv('data/Electric_Vehicle_Population_Data.csv')

# Dashboard introduction
st.title('Electric Vehicle Population Data Dashboard')
st.markdown('''Explore the electric vehicle data interactively using this dashboard.
This dashboard helps experts and stakeholders understand the distribution and characteristics of electric vehicles
in various counties and cities.''')

# Dashboard usage explanation
st.markdown('''### How to Use This Dashboard
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.

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.

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.

The map is also interactive; you can zoom in, rotate, and click on points to see additional information about each vehicle.''')

# Extract latitude and longitude from 'Vehicle Location' column
ev_data[['Longitude', 'Latitude']] = ev_data['Vehicle Location'].str.extract(r'POINT \((-?\d+\.\d+) (-?\d+\.\d+)\)')
ev_data['Latitude'] = pd.to_numeric(ev_data['Latitude'], errors='coerce')
ev_data['Longitude'] = pd.to_numeric(ev_data['Longitude'], errors='coerce')

# Sidebar filter options
county_list = ev_data['County'].unique()
make_list = ev_data['Make'].unique()

selected_county = st.sidebar.selectbox('Select County', county_list)
selected_make = st.sidebar.multiselect('Select Make', make_list, default=make_list)

# Filter data based on sidebar selections
filtered_data = ev_data[(ev_data['County'] == selected_county) & (ev_data['Make'].isin(selected_make))]

# Display filtered data
st.subheader('Filtered Data')
st.write(filtered_data)

# Interactive Bar Chart - Vehicle Count by Make
st.subheader('Vehicle Count by Make')
make_counts = filtered_data['Make'].value_counts().reset_index()
make_counts.columns = ['Make', 'Count']

def create_bar_chart(selected_make=None):
    # If a make is selected, highlight it in blue, otherwise default to green
    if selected_make:
        make_counts['Color'] = make_counts['Make'].apply(
            lambda x: 'blue' if x == selected_make else 'green'
        )
        color_map = make_counts.set_index('Make')['Color']
    else:
        color_map = 'green'

    # Create a bar chart showing vehicle count by make
    chart = px.bar(
        make_counts,
        x='Make',
        y='Count',
        title="Vehicle Count by Make",
        labels={'Make': 'Vehicle Make', 'Count': 'Number of Vehicles'},
        color='Make',
        color_discrete_map=color_map if isinstance(color_map, dict) else None
    )
    chart.update_layout(clickmode='event+select')  # Enable click interactions
    return chart

# Display the bar chart and capture click data
bar_chart = create_bar_chart(st.session_state.get('selected_make', None))
clicked_points = plotly_events(bar_chart, click_event=True, hover_event=False, select_event=False)

# Update the selected make based on user interaction
if clicked_points:
    st.session_state['selected_make'] = clicked_points[0]['x']  # Get clicked make
else:
    st.session_state['selected_make'] = None

# Display selected make
selected_make = st.session_state['selected_make']
if selected_make:
    st.write(f"Selected Make: {selected_make}")

# Filter data for the line chart based on selected make
if selected_make:
    filtered_data = ev_data[ev_data['Make'] == selected_make]
else:
    filtered_data = ev_data

# Group data by model year for the filtered data
model_year_data = filtered_data.groupby('Model Year').size().reset_index(name='Count')

# Create the line chart for model count by year
st.subheader(f"Number of Vehicles by Model Year for {selected_make if selected_make else 'All Makes'}")
line_chart = px.line(
    model_year_data,
    x='Model Year',
    y='Count',
    title=f"Number of Vehicles by Model Year for {selected_make if selected_make else 'All Makes'}",
    labels={'Model Year': 'Year', 'Count': 'Number of Vehicles'},
    markers=True
)

# Display the line chart
st.plotly_chart(line_chart, use_container_width=True)

# Interactive Map of Vehicle Locations
st.subheader('Map of Vehicle Locations')
filtered_data = filtered_data.dropna(subset=['Latitude', 'Longitude'])
filtered_data.rename(columns={'Latitude': 'latitude', 'Longitude': 'longitude'}, inplace=True)

# Create an interactive map using PyDeck
st.pydeck_chart(pdk.Deck(
    initial_view_state=pdk.ViewState(
        latitude=filtered_data['latitude'].mean(),
        longitude=filtered_data['longitude'].mean(),
        zoom=10,
    ),
    layers=[
        pdk.Layer(
            'ScatterplotLayer',
            data=filtered_data,
            get_position='[longitude, latitude]',
            get_radius=200,
            get_color='[200, 30, 0, 160]',
            pickable=True
        )
    ],
    tooltip={
        "html": "<b>Make:</b> {Make}<br/><b>Model:</b> {Model}<br/><b>Electric Range:</b> {Electric Range}",
        "style": {
            "backgroundColor": "steelblue",
            "color": "white"
        }
    }
))

# Contextual datasets
st.markdown('''### Contextual Datasets
A potentially useful contextual dataset could be the [Electric Charging Stations Locations](https://afdc.energy.gov/fuels/electricity_locations.html).
This dataset will provide information about the availability of charging stations in each county, allowing for a deeper
analysis of the convenience and accessibility of electric vehicles in different regions.''')

# Dataset size comment
st.markdown('''### Dataset Size
This dataset is uploaded huggingface repo using Git LFS, so there is no need to revise the plan for hosting this data.''')