ralate2 commited on
Commit
0972530
·
verified ·
1 Parent(s): 140971e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -48
app.py CHANGED
@@ -4,11 +4,11 @@ import numpy as np
4
  import matplotlib.pyplot as plt
5
  import seaborn as sns
6
  import altair as alt
 
7
  import folium
8
  from folium.plugins import HeatMap
9
  from streamlit_folium import st_folium
10
  import plotly.express as px
11
- from datetime import datetime
12
 
13
  # Set page config
14
  st.set_page_config(page_title="Nuisance Complaints Dashboard", layout="wide")
@@ -73,7 +73,8 @@ year_options = ['All Time'] + sorted(data['Year Reported'].unique().tolist())
73
  selected_year = st.sidebar.selectbox("Select Year", options=year_options)
74
  viz_type = st.sidebar.selectbox("Select Visualization", [
75
  "Complaint Types", "Geographic Distribution", "Resolution Status",
76
- "Submission Methods", "Complaints by Disposition", "Monthly Trends by Complaint Type"
 
77
  ])
78
 
79
  # Filter data based on year
@@ -99,10 +100,6 @@ if viz_type == "Complaint Types":
99
  complaint_counts.columns = ['Complaint Type', 'Count']
100
  fig = px.pie(complaint_counts, names='Complaint Type', values='Count', hole=0.4)
101
  st.plotly_chart(fig, use_container_width=True)
102
- st.write("""
103
- **Write-up:** This visualization shows the distribution of complaint types as a donut chart.
104
- It provides a quick overview of the most common complaints. The warm color palette helps
105
- highlight differences between complaint categories.""")
106
 
107
  elif viz_type == "Geographic Distribution":
108
  st.subheader("Clustered Heatmap of Complaints")
@@ -111,68 +108,68 @@ elif viz_type == "Geographic Distribution":
111
  heat_data = filtered_data[['Latitude', 'Longitude']].dropna().values.tolist()
112
  HeatMap(heat_data).add_to(m)
113
  st_folium(m, width=700, height=500)
114
- st.write("""
115
- **Write-up:** This heatmap visualizes complaint hotspots geographically. Areas with
116
- higher complaint density are highlighted, helping policymakers focus resources effectively.""")
117
 
118
  elif viz_type == "Resolution Status":
119
  st.subheader("Interactive Complaint Resolution Status")
120
  resolution_counts = filtered_data['Disposition'].value_counts().reset_index()
121
  resolution_counts.columns = ['Disposition', 'Count']
122
- resolution_counts['Percentage'] = (resolution_counts['Count'] / resolution_counts['Count'].sum()) * 100
123
  chart = alt.Chart(resolution_counts).mark_arc(innerRadius=50).encode(
124
  theta=alt.Theta(field="Count", type="quantitative"),
125
- color=alt.Color(field="Disposition", type="nominal"),
126
- tooltip=[
127
- alt.Tooltip("Disposition", title="Resolution"),
128
- alt.Tooltip("Count", title="Count"),
129
- alt.Tooltip("Percentage", title="Percentage", format=".2f")
130
- ]
131
- )
132
- st.altair_chart(chart, use_container_width=True)
133
- st.write("""
134
- **Write-up:** This chart visualizes resolution status using a donut chart.
135
- It provides insights into the efficiency of complaint resolutions.""")
136
-
137
- elif viz_type == "Monthly Trends by Complaint Type":
138
- st.subheader("Monthly Trends Grouped by Complaint Types")
139
- monthly_trends = (
140
- filtered_data.groupby(['Month Reported', 'Type of Complaint'])
141
- .size()
142
- .reset_index(name='Count')
143
- )
144
- monthly_trends['Month'] = monthly_trends['Month Reported'].apply(
145
- lambda x: datetime(2023, x, 1).strftime('%B')
146
- )
147
- chart = alt.Chart(monthly_trends).mark_line(point=True).encode(
148
- x=alt.X('Month Reported:O', title='Month'),
149
- y=alt.Y('Count:Q', title='Number of Complaints'),
150
- color=alt.Color('Type of Complaint:N', title='Complaint Type'),
151
- tooltip=["Type of Complaint:N", "Month:N", "Count:Q"]
152
  )
153
  st.altair_chart(chart, use_container_width=True)
154
- st.write("""
155
- **Write-up:** This line chart visualizes monthly trends in complaints grouped by type.
156
- The use of vibrant colors helps distinguish trends across different complaint types.""")
157
 
158
  elif viz_type == "Submission Methods":
159
  st.subheader("Submission Methods Analysis")
160
  submission_counts = filtered_data['Method Submitted'].value_counts()
161
  fig, ax = plt.subplots(figsize=(10, 6))
162
  sns.barplot(x=submission_counts.values, y=submission_counts.index, palette='inferno', ax=ax)
163
- ax.set_title(f"Submission Methods in {selected_year}")
164
  st.pyplot(fig)
165
- st.write("""
166
- **Write-up:** This bar chart illustrates the preferred methods for complaint submission.
167
- The `inferno` color palette highlights differences across submission types.""")
168
 
169
  elif viz_type == "Complaints by Disposition":
170
  st.subheader("Complaints by Disposition")
171
  disposition_counts = filtered_data['Disposition'].value_counts()
172
  fig, ax = plt.subplots(figsize=(10, 6))
173
  sns.barplot(x=disposition_counts.values, y=disposition_counts.index, palette='viridis', ax=ax)
174
- ax.set_title(f"Complaints by Disposition in {selected_year}")
175
  st.pyplot(fig)
176
- st.write("""
177
- **Write-up:** This bar chart shows the distribution of complaints across various dispositions.
178
- The `viridis` color palette effectively highlights disposition categories.""")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import matplotlib.pyplot as plt
5
  import seaborn as sns
6
  import altair as alt
7
+ from datetime import datetime
8
  import folium
9
  from folium.plugins import HeatMap
10
  from streamlit_folium import st_folium
11
  import plotly.express as px
 
12
 
13
  # Set page config
14
  st.set_page_config(page_title="Nuisance Complaints Dashboard", layout="wide")
 
73
  selected_year = st.sidebar.selectbox("Select Year", options=year_options)
74
  viz_type = st.sidebar.selectbox("Select Visualization", [
75
  "Complaint Types", "Geographic Distribution", "Resolution Status",
76
+ "Submission Methods", "Complaints by Disposition", "Monthly Trends by Complaint Type",
77
+ "Top Complaint Types", "Complaints Over Time", "Complaints by Housing Block and Type"
78
  ])
79
 
80
  # Filter data based on year
 
100
  complaint_counts.columns = ['Complaint Type', 'Count']
101
  fig = px.pie(complaint_counts, names='Complaint Type', values='Count', hole=0.4)
102
  st.plotly_chart(fig, use_container_width=True)
 
 
 
 
103
 
104
  elif viz_type == "Geographic Distribution":
105
  st.subheader("Clustered Heatmap of Complaints")
 
108
  heat_data = filtered_data[['Latitude', 'Longitude']].dropna().values.tolist()
109
  HeatMap(heat_data).add_to(m)
110
  st_folium(m, width=700, height=500)
 
 
 
111
 
112
  elif viz_type == "Resolution Status":
113
  st.subheader("Interactive Complaint Resolution Status")
114
  resolution_counts = filtered_data['Disposition'].value_counts().reset_index()
115
  resolution_counts.columns = ['Disposition', 'Count']
 
116
  chart = alt.Chart(resolution_counts).mark_arc(innerRadius=50).encode(
117
  theta=alt.Theta(field="Count", type="quantitative"),
118
+ color=alt.Color(field="Disposition", type="nominal")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  )
120
  st.altair_chart(chart, use_container_width=True)
 
 
 
121
 
122
  elif viz_type == "Submission Methods":
123
  st.subheader("Submission Methods Analysis")
124
  submission_counts = filtered_data['Method Submitted'].value_counts()
125
  fig, ax = plt.subplots(figsize=(10, 6))
126
  sns.barplot(x=submission_counts.values, y=submission_counts.index, palette='inferno', ax=ax)
 
127
  st.pyplot(fig)
 
 
 
128
 
129
  elif viz_type == "Complaints by Disposition":
130
  st.subheader("Complaints by Disposition")
131
  disposition_counts = filtered_data['Disposition'].value_counts()
132
  fig, ax = plt.subplots(figsize=(10, 6))
133
  sns.barplot(x=disposition_counts.values, y=disposition_counts.index, palette='viridis', ax=ax)
 
134
  st.pyplot(fig)
135
+
136
+ elif viz_type == "Monthly Trends by Complaint Type":
137
+ st.subheader("Monthly Trends Grouped by Complaint Types")
138
+ monthly_trends = filtered_data.groupby(['Month Reported', 'Type of Complaint']).size().reset_index(name='Count')
139
+ chart = alt.Chart(monthly_trends).mark_line(point=True).encode(
140
+ x=alt.X('Month Reported:O', title='Month'),
141
+ y=alt.Y('Count:Q', title='Number of Complaints'),
142
+ color='Type of Complaint:N'
143
+ )
144
+ st.altair_chart(chart, use_container_width=True)
145
+
146
+ elif viz_type == "Top Complaint Types":
147
+ st.subheader("Top Complaint Types")
148
+ complaint_counts = filtered_data['Type of Complaint'].value_counts().head(10)
149
+ fig, ax = plt.subplots()
150
+ sns.barplot(x=complaint_counts.values, y=complaint_counts.index, palette="inferno", ax=ax)
151
+ st.pyplot(fig)
152
+
153
+ elif viz_type == "Complaints Over Time":
154
+ st.subheader("Complaints Over Time")
155
+ complaints_over_time = filtered_data.groupby(filtered_data['Date Reported'].dt.date).size()
156
+ fig, ax = plt.subplots()
157
+ ax.plot(complaints_over_time.index, complaints_over_time.values, marker='o')
158
+ ax.set_title("Complaints Over Time")
159
+ st.pyplot(fig)
160
+
161
+ elif viz_type == "Complaints by Housing Block and Type":
162
+ st.subheader("Complaints by Housing Block and Type")
163
+ complaint_pivot = filtered_data.pivot_table(
164
+ index='Housing Block',
165
+ columns='Type of Complaint',
166
+ values='Disposition',
167
+ aggfunc='count',
168
+ fill_value=0
169
+ )
170
+ fig = complaint_pivot.plot(kind='bar', stacked=True, colormap='inferno', figsize=(10, 6)).get_figure()
171
+ st.pyplot(fig)
172
+
173
+ # Footer
174
+ st.markdown("---")
175
+ st.markdown("Dataset provided by the City of Urbana Open Data Portal.")