vgosavi2 commited on
Commit
64f90bb
·
verified ·
1 Parent(s): 12311a5

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +70 -30
src/streamlit_app.py CHANGED
@@ -44,24 +44,53 @@ st.markdown("""
44
  .title {
45
  text-align: center;
46
  padding: 25px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
  </style>
49
  """, unsafe_allow_html=True)
50
-
 
51
  st.markdown("<div class='title'><h1> LAPD Crime Insights Dashboard </h1></div>", unsafe_allow_html=True)
52
 
53
- # 1. Page title
54
- st.markdown(""" This application provides a suite of interactive visualizations—pie charts, bar charts, scatter plots, and more—that let you explore crime patterns in the LAPD dataset from multiple angles. Quickly see which offense categories dominate, compare arrest rates against non-arrests, track how crime volumes change over time, and examine geographic hotspots. These insights can help police departments, community organizations, and policymakers allocate resources more effectively and design targeted strategies to improve public safety.""")
55
-
 
 
 
56
  # 2. Data info & load
57
- st.header("Dataset Information")
58
  st.markdown(
59
- """
60
- - **Source:** LAPD crime incidents dataset
61
- - **Rows:** incidents (one per row)
62
- - **Columns:** e.g. `crm_cd_desc` (crime type), `arrest` (boolean), `date`, `location_description`, etc.
63
- - **Purpose:** Interactive exploration of top crime categories and arrest rates.
64
- """
 
 
 
 
 
65
  )
66
 
67
  # # Define paths.
@@ -82,7 +111,7 @@ st.markdown(
82
  def load_data():
83
  return pd.read_csv(DATA_PATH)
84
 
85
- if st.button("🔄"):
86
  st.cache_data.clear() # Clear the cache
87
  st.toast("Data is refreshed",icon="✅") # Reload the data
88
 
@@ -92,26 +121,32 @@ if df.empty:
92
  st.stop()
93
 
94
  # 3. Data preview
95
- st.header("Data Preview")
96
- st.write(f"Total records: {df.shape[0]} | Total columns: {df.shape[1]}")
 
 
 
 
 
 
97
  st.dataframe(df.head())
98
 
99
  # Pie Chart 1: Top 10 Crime Types
100
- st.markdown("<div class='title'><h1> Top 10 Crime Type </h1></div>", unsafe_allow_html=True)
101
 
102
  years = sorted(df["year"].dropna().astype(int).unique())
103
  # Prepend an “All” option
104
  options = ["All"] + years
105
-
106
- # Year filter (shorter, above chart)
107
- col_empty, col_filter = st.columns([3,1])
108
- with col_filter:
109
- selected_year = st.selectbox(
110
- "Select Year",
111
- options=options,
112
- index=0, # default to “All”
113
- key="year_filter"
114
- )
115
 
116
  # Filter according to selection
117
  if selected_year == "All":
@@ -161,14 +196,15 @@ fig = px.pie(
161
  fig.update_traces(
162
  textposition="outside",
163
  textinfo="label+percent",
164
- pull=[0.05] * len(top_crimes),
165
- marker=dict(line=dict(color="white", width=2))
166
  )
167
 
168
  fig.update_layout(
169
  legend_title_text="Crime Type",
170
- margin=dict(t=60, b=20, l=20, r=20),
171
- height=700,
 
172
  title_x=0.5
173
  )
174
 
@@ -176,7 +212,11 @@ fig.update_layout(
176
  st.plotly_chart(fig, use_container_width=True)
177
 
178
  # Description.
179
- st.markdown(""" The donut chart shows the share of the ten most frequent crime categories in the selected year. At the center, you can see that Vehicle ­– Stolen is the single largest slice, accounting for roughly 18.7% of all incidents, The remaining five categories each represent between 3%–5% of total incidents—these include miscellaneous crimes, criminal threats, assault with a deadly weapon, burglary, and minor vandalism. By displaying both slice size and percentage labels, the chart makes it easy to compare how dominant property‐related offenses are, versus violent or lesser‐common crimes, in that year’s LAPD data. """)
 
 
 
 
180
 
181
 
182
  # -------------------------------- Plot 2: Heat Map --------------------------------
 
44
  .title {
45
  text-align: center;
46
  padding: 25px;
47
+ color: #2c3e50;
48
+ font-family: 'Source Sans Pro', sans-serif;
49
+ }
50
+ /* Paragraph/write-up styling */
51
+ .description {
52
+ font-size: 18px; /* comfortable reading size */
53
+ line-height: 1.6; /* good spacing */
54
+ color: #4b4b4b; /* dark grey text */
55
+ text-align: justify; /* nice full-justified look */
56
+ padding: 0 10px 20px; /* side & bottom padding */
57
+ font-family: 'Helvetica Neue', Arial, sans-serif;
58
+ }
59
+ .sectionheader {
60
+ font-family: 'Source Sans Pro', sans-serif;
61
+ font-size: 32px;
62
+ color: #2c3e50;
63
+ margin-top: 15px;
64
+ margin-bottom: 10px;
65
+ border-bottom: 3px solid #ccc;
66
+ padding-bottom: 8px;
67
  }
68
  </style>
69
  """, unsafe_allow_html=True)
70
+
71
+ # 1. Page title
72
  st.markdown("<div class='title'><h1> LAPD Crime Insights Dashboard </h1></div>", unsafe_allow_html=True)
73
 
74
+ st.markdown("""<div class='description'> This application provides a suite of interactive visualizations—pie charts,
75
+ bar charts, scatter plots, and more—that let you explore crime patterns in the LAPD dataset from multiple angles.
76
+ Quickly see which offense categories dominate, compare arrest rates against non-arrests, track how crime volumes change over time, and examine geographic hotspots.
77
+ These insights can help police departments, community organizations, and policymakers allocate resources more effectively and
78
+ design targeted strategies to improve public safety.</div>""",unsafe_allow_html=True)
79
+
80
  # 2. Data info & load
81
+ st.markdown("<div class='sectionheader'> Dataset Information </div>", unsafe_allow_html=True)
82
  st.markdown(
83
+ """
84
+ <div class="description">
85
+ <ul>
86
+ <li><strong>Source:</strong> LAPD crime incidents dataset</li>
87
+ <li><strong>Rows:</strong> one incident per row</li>
88
+ <li><strong>Columns:</strong> e.g. <code>crm_cd_desc</code> (crime type), <code>arrest</code> (boolean), <code>year</code>, <code>location_description</code>, etc.</li>
89
+ <li><strong>Purpose:</strong> Interactive exploration of top crime categories and arrest rates.</li>
90
+ </ul>
91
+ </div>
92
+ """,
93
+ unsafe_allow_html=True
94
  )
95
 
96
  # # Define paths.
 
111
  def load_data():
112
  return pd.read_csv(DATA_PATH)
113
 
114
+ if st.button("🔄 Refresh Data"):
115
  st.cache_data.clear() # Clear the cache
116
  st.toast("Data is refreshed",icon="✅") # Reload the data
117
 
 
121
  st.stop()
122
 
123
  # 3. Data preview
124
+ st.markdown("<div class='sectionheader'> Data Preview </div>", unsafe_allow_html=True)
125
+ st.markdown(
126
+ f"<div class='description'>"
127
+ f"Total records: <strong>{df.shape[0]:,}</strong> &nbsp;|&nbsp; "
128
+ f"Total columns: <strong>{df.shape[1]:,}</strong>"
129
+ f"</div>",
130
+ unsafe_allow_html=True
131
+ )
132
  st.dataframe(df.head())
133
 
134
  # Pie Chart 1: Top 10 Crime Types
135
+ st.markdown("<div class='sectionheader'> Top 10 Crime Types by Year </div>", unsafe_allow_html=True)
136
 
137
  years = sorted(df["year"].dropna().astype(int).unique())
138
  # Prepend an “All” option
139
  options = ["All"] + years
140
+ selected_year = st.selectbox("Select Year", options, index=0)
141
+ # # Year filter (shorter, above chart)
142
+ # col_empty, col_filter = st.columns([3,1])
143
+ # with col_filter:
144
+ # selected_year = st.selectbox(
145
+ # "Select Year",
146
+ # options=options,
147
+ # index=0, # default to “All”
148
+ # key="year_filter"
149
+ # )
150
 
151
  # Filter according to selection
152
  if selected_year == "All":
 
196
  fig.update_traces(
197
  textposition="outside",
198
  textinfo="label+percent",
199
+ pull=[0.02] * len(top_crimes),
200
+ marker=dict(line=dict(color="white", width=1))
201
  )
202
 
203
  fig.update_layout(
204
  legend_title_text="Crime Type",
205
+ margin=dict(t=40, b=40, l=20, r=20),
206
+ height=600,
207
+ width=450,
208
  title_x=0.5
209
  )
210
 
 
212
  st.plotly_chart(fig, use_container_width=True)
213
 
214
  # Description.
215
+ st.markdown("""<div class="description"> The donut chart shows the share of the ten most frequent crime categories in the selected year.
216
+ At the center, you can see that Vehicle ­– Stolen is the single largest slice, accounting for roughly 18.7% of all incidents,
217
+ The remaining five categories each represent between 3%–5% of total incidents—these include miscellaneous crimes, criminal threats,
218
+ assault with a deadly weapon, burglary, and minor vandalism. By displaying both slice size and percentage labels, the chart makes it easy
219
+ to compare how dominant property‐related offenses are, versus violent or lesser‐common crimes, in that year’s LAPD data.</div>""",unsafe_allow_html=True)
220
 
221
 
222
  # -------------------------------- Plot 2: Heat Map --------------------------------