#!/usr/bin/env python
# coding: utf-8
# Shooting Events in Philadelphia, PA (2015 to 2023)
# In[55]:
import carto2gpd
from folium.plugins import HeatMap, MarkerCluster
import folium
import geopandas as gpd
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
import osmnx as ox
# Using OpenDataPhilly's API, I accessed the data on shooting events.
# In[63]:
# Get shooting data from Open Data Philly's API
url = "https://phl.carto.com/api/v2/sql"
table_name = "shootings"
df = carto2gpd.get(url, table_name)
df = df.loc[df['year'] != 2023] # Use only full year's worth of data
df
# The line plot below shows a steady amount of shooting events from 2015 to 2019, with a sporadic increase in shooting events from 2019 to 2020.
# In[29]:
# Organize counts of shootings by year
by_year = df.groupby('year').size().reset_index(name='Count')
# Set up the plot and plot the line graph
sns.set_style("darkgrid")
plt.figure(figsize=(10, 6))
sns.lineplot(x='year', y='Count', data=by_year, marker='o', color='#5eccab', linewidth=2.5)
plt.xlabel('Year')
plt.ylabel('Count')
plt.title('Count of Shootings - Philadelphia, PA (2015 to 2023)')
plt.gca().set_facecolor('black')
plt.tick_params(colors='black')
plt.xlabel('Year', color='black')
plt.ylabel('Count', color='black')
plt.show()
# Using Folium, I plotted all of the data points, colored by the year they occurred. I leveraged marker clustering so that way not all ~14,000 points appeared on the map at once, but rather you can zoom into an area of interest. Using a tooltip, I added information about the year, age, sex, and race of the offender, if the offender was injured or deceased, and whether an officer was involved.
# In[62]:
import folium
from folium.plugins import MarkerCluster
# Filter out rows with missing geometries
df2 = df.dropna(subset=['point_x', 'point_y'])
# Create a map centered on the calculated location
f = folium.Map(location=[39.99, -75.13], zoom_start=10, tiles='Cartodb dark_matter')
# Define a colormap for different years
cm = {
2015: '#546319',
2016: '#c0affb',
2017: '#e6a176',
2018: '#00678a',
2019: '#984464',
2020: '#5eccab',
2021: '#cdcdcd',
2022: '#ddcc77'
}
# Create a marker cluster to help with map performance and aesthetics
marker_cluster = MarkerCluster().add_to(f)
# Iterate over the filtered dataframe rows
for index, row in df2.iterrows():
latitude = row['point_y']
longitude = row['point_x']
year = row['year']
color = cm.get(year, year)
race = row['race']
sex = row['sex']
age = row['age']
officer_involved = row['officer_involved']
offender_injured = row['offender_injured']
offender_deceased = row['offender_deceased']
tooltip = f"Year: {year}
Race: {race}
Age: {age}
Sex: {sex}
Officer Involved: {officer_involved}
Offender Injured: {offender_injured}
Offender Deceased: {offender_deceased}"
folium.CircleMarker(
location=[latitude, longitude],
radius=5,
alpha=0.5,
color=color,
fill=True,
fill_color=color,
tooltip=tooltip
).add_to(marker_cluster)
# Add title to the map
title_html = '''