vgosavi2 commited on
Commit
6b3ed66
·
verified ·
1 Parent(s): 81c56cb

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +49 -47
src/streamlit_app.py CHANGED
@@ -230,7 +230,7 @@ criminal threats and minor burglary. Violent acts such as simple assault and rob
230
  relying on specific numbers. By pairing each slice with its label, the chart provides an immediate intuitive understanding of which crime types contribute most to overall
231
  volume and which are comparatively rare, helping stakeholders focus on the offenses that matter most.</div>""",unsafe_allow_html=True)
232
 
233
- # -------------------------------- Plot 6: Bubble Map of Incident Counts by Region --------------------------------
234
  # st.markdown("<div class='sectionheader'>Crime Hotspots by Region</div>", unsafe_allow_html=True)
235
 
236
  # # 1. Aggregate counts and centroids
@@ -270,46 +270,7 @@ volume and which are comparatively rare, helping stakeholders focus on the offen
270
  # # 4. Render
271
  # st.plotly_chart(fig, use_container_width=True)
272
 
273
- # -------------------------------- Plot 7: Line Chart for Incident Counts by Region --------------------------------
274
- st.markdown("<div class='sectionheader'>Incidents Trends over Time </div>", unsafe_allow_html=True)
275
- # 1. Aggregate total incidents by year
276
- yearly_region = (
277
- df
278
- .groupby(["year", "RegionName"])
279
- .size()
280
- .reset_index(name="Count")
281
- )
282
-
283
- # 2. Let the user pick one region to highlight
284
- regions = sorted(yearly_region["RegionName"].unique())
285
- sel_region = st.selectbox("Select Region", ["All"] + regions, index=0)
286
-
287
- if sel_region != "All":
288
- yearly_region = yearly_region[yearly_region["RegionName"] == sel_region]
289
-
290
- # 3. Plot a smooth line per region (or just the one selected)
291
- fig = px.line(
292
- yearly_region,
293
- x="year",
294
- y="Count",
295
- color="RegionName",
296
- title=(" "),
297
- labels={"year":"Year", "Count":"Incident Count"}
298
- )
299
-
300
- # 4. Add LOWESS smoothing (optional)
301
- for trace in fig.data:
302
- trace.update(mode="lines") # remove markers
303
-
304
- st.plotly_chart(fig, use_container_width=True)
305
- # Description.
306
- st.markdown("""<div class="description"> This multi‐line chart tracks how total crime incidents have evolved across LAPD regions from 2020
307
- through 2025. Each colored line represents a different precinct, letting you compare their trajectories side by side. You’ll notice that most
308
- areas rose to a peak around 2022 before tapering off, while a handful of regions bucked the trend—either holding steady or dipping earlier. The
309
- clear visual of converging and diverging lines makes it easy to spot which precincts saw the sharpest upticks, which managed to keep incidents
310
- relatively flat, and how the overall pattern shifted over the five‐year span.</div>""",unsafe_allow_html=True)
311
-
312
- # -------------------------------- Plot 8: Stacked Bar Charts for Regions --------------------------------
313
  st.markdown("<div class='sectionheader'>Crime Composition by Region: Top 5 Offenses </div>", unsafe_allow_html=True)
314
  # 1. Compute counts per region and crime
315
  counts = (
@@ -357,7 +318,48 @@ violent or specialty offenses. By grouping all five slices together, the visuali
357
  for example, precincts where assault plays a disproportionately large role versus those driven mainly by theft. This makes it straightforward to compare how
358
  offense patterns differ from one region to the next.</div>""",unsafe_allow_html=True)
359
 
360
- # -------------------------------- Plot 7: Bubble Map of Incident Counts by Region NO MAP --------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  # st.markdown("<div class='sectionheader'>Crime Hotspots by Region NO MAP</div>", unsafe_allow_html=True)
362
 
363
  # # 1. Aggregate total incidents by region and pick top 10
@@ -392,7 +394,7 @@ offense patterns differ from one region to the next.</div>""",unsafe_allow_html=
392
  # # 4. Render in Streamlit
393
  # st.plotly_chart(fig, use_container_width=True)
394
 
395
- # -------------------------------- Plot 2: Heat Map --------------------------------
396
  st.markdown("<div class='sectionheader'> HeatMap </div>", unsafe_allow_html=True)
397
  # Count the crime type and list out the top 10 crime type that have the most cases.
398
  top_crimes = df['crm_cd_desc'].value_counts().nlargest(10).index
@@ -436,7 +438,7 @@ This heatmap shows the frequency of the top 10 crimes from 2020 to 2025. The x a
436
  </div>""",unsafe_allow_html=True)
437
 
438
 
439
- # -------------------------------- Plot 3: Line Chart --------------------------------
440
  st.markdown("<div class='sectionheader'> Line Chart </div>", unsafe_allow_html=True)
441
  # Filter out the year 2025 since it is not the end, so that the trend can't be see.
442
  df = df[df['year'] != 2025]
@@ -476,7 +478,7 @@ crime type: Battery - Simple Assault, Burglary From Vehicle, Theft of Identity,
476
  the fluctuations and overall trajectories of these major crime categories across the years.</div>""",unsafe_allow_html=True)
477
 
478
 
479
- # -------------------------------- Plot 4: Map --------------------------------
480
  st.markdown("<div class='sectionheader'> Explore LA Crime Patterns: An Interactive Folium Map </div>", unsafe_allow_html=True)
481
  # Load the data.
482
  with open(GEOJSON_PATH, "r", encoding="utf-8") as f:
@@ -543,7 +545,7 @@ st.markdown("""<div class="description">
543
  This visualization uses Folium to build an interactive map of crime distribution in Los Angeles, highlighting the geospatial clustering characteristics of different years and crime types, and emphasizing the user's experience of freely exploring the map. The base map uses real streets and geographic backgrounds to enhance the spatial visualization of the image. The map shows the administrative boundaries of Los Angeles County in blue polygons, which are loaded with GeoJSON data and overlaid on the map to specify the geographic boundaries of crime locations. The red dots on the map represent the location of individual crimes, and the system samples no more than 300 data items from this category for visualization, with each dot pinpointed by latitude and longitude coordinates. The map supports full Leaflet.js functionality, including zooming, dragging, layer control, and other operations, which greatly enhances the flexibility of data exploration. A drop-down menu in the upper left corner of the page allows users to customize filters for specific years and crime types, enabling instant updates to the map content.
544
  </div>""",unsafe_allow_html=True)
545
 
546
- # -------------------------------- Plot 4: Stacked Bar Chart --------------------------------
547
  st.markdown("<div class='sectionheader'>Trends in Top 10 Crime Types (2020–2024)</div>", unsafe_allow_html=True)
548
  # Group by crime type and year.
549
  stacked_year_df = df_top.groupby(['year', 'crm_cd_desc']).size().reset_index(name='count')
@@ -570,7 +572,7 @@ Description: Our stacked bar chart shows the number of reported crimes for the t
570
  By observing the plot, we can find out that 2022 had the most crimes, the year had the second most crimes is 2023, and etc. Besides that, we can also find out that some crimes, like vehicle theft, petty theft, and burglary from vehicles, happened a lot every year and make up a big part of the total.
571
  </div>""",unsafe_allow_html=True)
572
 
573
- # -------------------------------- Plot 5: Bar Chart --------------------------------
574
  st.markdown("<div class='sectionheader'>Crime Rankings for Selected Year</div>", unsafe_allow_html=True)
575
  # Group by crime type and year.
576
  heatmap1_df = df_top.groupby(['crm_cd_desc', 'year']).size().reset_index(name='count')
 
230
  relying on specific numbers. By pairing each slice with its label, the chart provides an immediate intuitive understanding of which crime types contribute most to overall
231
  volume and which are comparatively rare, helping stakeholders focus on the offenses that matter most.</div>""",unsafe_allow_html=True)
232
 
233
+ # -------------------------------- Plot : Bubble Map of Incident Counts by Region --------------------------------
234
  # st.markdown("<div class='sectionheader'>Crime Hotspots by Region</div>", unsafe_allow_html=True)
235
 
236
  # # 1. Aggregate counts and centroids
 
270
  # # 4. Render
271
  # st.plotly_chart(fig, use_container_width=True)
272
 
273
+ # -------------------------------- Plot 2: Stacked Bar Charts for Regions --------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  st.markdown("<div class='sectionheader'>Crime Composition by Region: Top 5 Offenses </div>", unsafe_allow_html=True)
275
  # 1. Compute counts per region and crime
276
  counts = (
 
318
  for example, precincts where assault plays a disproportionately large role versus those driven mainly by theft. This makes it straightforward to compare how
319
  offense patterns differ from one region to the next.</div>""",unsafe_allow_html=True)
320
 
321
+ # -------------------------------- Plot 3: Line Chart for Incident Counts by Region --------------------------------
322
+ st.markdown("<div class='sectionheader'>Incidents Trends over Time </div>", unsafe_allow_html=True)
323
+ # 1. Aggregate total incidents by year
324
+ yearly_region = (
325
+ df
326
+ .groupby(["year", "RegionName"])
327
+ .size()
328
+ .reset_index(name="Count")
329
+ )
330
+
331
+ # 2. Let the user pick one region to highlight
332
+ regions = sorted(yearly_region["RegionName"].unique())
333
+ sel_region = st.selectbox("Select Region", ["All"] + regions, index=0)
334
+
335
+ if sel_region != "All":
336
+ yearly_region = yearly_region[yearly_region["RegionName"] == sel_region]
337
+
338
+ # 3. Plot a smooth line per region (or just the one selected)
339
+ fig = px.line(
340
+ yearly_region,
341
+ x="year",
342
+ y="Count",
343
+ color="RegionName",
344
+ title=(" "),
345
+ labels={"year":"Year", "Count":"Incident Count"}
346
+ )
347
+
348
+ # 4. Add LOWESS smoothing (optional)
349
+ for trace in fig.data:
350
+ trace.update(mode="lines") # remove markers
351
+
352
+ st.plotly_chart(fig, use_container_width=True)
353
+ # Description.
354
+ st.markdown("""<div class="description"> This multi‐line chart tracks how total crime incidents have evolved across LAPD regions from 2020
355
+ through 2025. Each colored line represents a different precinct, letting you compare their trajectories side by side. You’ll notice that most
356
+ areas rose to a peak around 2022 before tapering off, while a handful of regions bucked the trend—either holding steady or dipping earlier. The
357
+ clear visual of converging and diverging lines makes it easy to spot which precincts saw the sharpest upticks, which managed to keep incidents
358
+ relatively flat, and how the overall pattern shifted over the five‐year span.</div>""",unsafe_allow_html=True)
359
+
360
+
361
+
362
+ # -------------------------------- Plot : Bubble Map of Incident Counts by Region NO MAP --------------------------------
363
  # st.markdown("<div class='sectionheader'>Crime Hotspots by Region NO MAP</div>", unsafe_allow_html=True)
364
 
365
  # # 1. Aggregate total incidents by region and pick top 10
 
394
  # # 4. Render in Streamlit
395
  # st.plotly_chart(fig, use_container_width=True)
396
 
397
+ # -------------------------------- Plot 4: Heat Map --------------------------------
398
  st.markdown("<div class='sectionheader'> HeatMap </div>", unsafe_allow_html=True)
399
  # Count the crime type and list out the top 10 crime type that have the most cases.
400
  top_crimes = df['crm_cd_desc'].value_counts().nlargest(10).index
 
438
  </div>""",unsafe_allow_html=True)
439
 
440
 
441
+ # -------------------------------- Plot 5: Line Chart --------------------------------
442
  st.markdown("<div class='sectionheader'> Line Chart </div>", unsafe_allow_html=True)
443
  # Filter out the year 2025 since it is not the end, so that the trend can't be see.
444
  df = df[df['year'] != 2025]
 
478
  the fluctuations and overall trajectories of these major crime categories across the years.</div>""",unsafe_allow_html=True)
479
 
480
 
481
+ # -------------------------------- Plot 6: Map --------------------------------
482
  st.markdown("<div class='sectionheader'> Explore LA Crime Patterns: An Interactive Folium Map </div>", unsafe_allow_html=True)
483
  # Load the data.
484
  with open(GEOJSON_PATH, "r", encoding="utf-8") as f:
 
545
  This visualization uses Folium to build an interactive map of crime distribution in Los Angeles, highlighting the geospatial clustering characteristics of different years and crime types, and emphasizing the user's experience of freely exploring the map. The base map uses real streets and geographic backgrounds to enhance the spatial visualization of the image. The map shows the administrative boundaries of Los Angeles County in blue polygons, which are loaded with GeoJSON data and overlaid on the map to specify the geographic boundaries of crime locations. The red dots on the map represent the location of individual crimes, and the system samples no more than 300 data items from this category for visualization, with each dot pinpointed by latitude and longitude coordinates. The map supports full Leaflet.js functionality, including zooming, dragging, layer control, and other operations, which greatly enhances the flexibility of data exploration. A drop-down menu in the upper left corner of the page allows users to customize filters for specific years and crime types, enabling instant updates to the map content.
546
  </div>""",unsafe_allow_html=True)
547
 
548
+ # -------------------------------- Plot 7: Stacked Bar Chart --------------------------------
549
  st.markdown("<div class='sectionheader'>Trends in Top 10 Crime Types (2020–2024)</div>", unsafe_allow_html=True)
550
  # Group by crime type and year.
551
  stacked_year_df = df_top.groupby(['year', 'crm_cd_desc']).size().reset_index(name='count')
 
572
  By observing the plot, we can find out that 2022 had the most crimes, the year had the second most crimes is 2023, and etc. Besides that, we can also find out that some crimes, like vehicle theft, petty theft, and burglary from vehicles, happened a lot every year and make up a big part of the total.
573
  </div>""",unsafe_allow_html=True)
574
 
575
+ # -------------------------------- Plot 8: Bar Chart --------------------------------
576
  st.markdown("<div class='sectionheader'>Crime Rankings for Selected Year</div>", unsafe_allow_html=True)
577
  # Group by crime type and year.
578
  heatmap1_df = df_top.groupby(['crm_cd_desc', 'year']).size().reset_index(name='count')