Welcome to the Unit 2 Final Deliverable. This deliverable includes five different visualizations of the same dataset. Embedded is the source code for each visualization.
This Dataset was created by the Los Angeles Police Department and includes all arrests in LA from 2020-2024. Each arrest includes data such as date, neighborhood, decription of offense and the sex of the individual arrested. This dataset is large, with hundreds of thousands of entries, so the following visualizations aim to analyze and find trends in the data.
I could not get the “Tab” function to properly work. After an hour of troubleshooting, I still could not figure it out, as my script is correct. As a result, I have opted for the more basic layout to display my findings.
This scatterplot displays arrests by age group in each neighborhood of LA. This scatterplot serves to display the age of citizens arrested in the various neighborhoods of LA, offering insight into the most common ages at which people are arrested.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
filename = 'Arrest_Data_from_2020_to_Present.csv'
df = pd.read_csv(filename, nrows=5)
print(df.columns)
df = pd.read_csv(filename, usecols = ['Age', 'Area Name'])
#Testing
df.shape
#Dataframe
x = df.groupby(['Age', 'Area Name'])['Age'].count().reset_index(name='count')
x = pd.DataFrame(x)
x
x['count'].max()
x.Age.value_counts()
#Data frame 2, omits ages younger than 13
omit = [0,1,2,3,4,5,6,7,8,9,10,11,12]
x2 = x.loc[ ~x['Age'].isin(omit)]
x2
x2['count_hundreds'] = round(x2['count']/10, 0)
x2
#Contents of chart
plt.figure(figsize=(18,10))
plt.scatter(x2['Age'], x2['Area Name'], marker='o', cmap='viridis',
c=x2['count_hundreds'], s=x2['count_hundreds'], edgecolors='black')
#Titles and labels
plt.title('Arrests by Age Group in each Neighborhood', fontsize=20)
plt.xlabel('Age Group', fontsize=18)
plt.ylabel('Neighborhood', fontsize=18)
cbar = plt.colorbar()
cbar.set_label('Number of Arrests', rotation =270, fontsize= 18, color='black', labelpad=30)
#Chart displays the amount of Arrests each age group has in each neighborhood of LA.
plt.show()
This heatmap displays the same data from the scatterplot, which is arrests by age group in each neighborhood of LA. This heatmap serves to show additional insight into the specific number of citizens per age group that were arrested in the various neighborhoods of LA. Note: The X axis label is “Neighborhood.” In Jupyter, this label displayed correctly, however after various attempts at troubleshooting, I was not able to have it properly display in R Markdown.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
filename = 'Arrest_Data_from_2020_to_Present.csv'
df = pd.read_csv(filename, nrows=5)
print(df.columns)
#Following code is used from the Scatterplot visualization
df = pd.read_csv(filename, usecols = ['Age', 'Area Name'])
df.shape
x = df.groupby(['Age', 'Area Name'])['Age'].count().reset_index(name='count')
x = pd.DataFrame(x)
x
x['count'].max()
x.Age.value_counts()
#Omitted ages younger than 13
omit = [0,1,2,3,4,5,6,7,8,9,10,11,12]
x2 = x.loc[ ~x['Age'].isin(omit)]
x2
x2['count_hundreds'] = round(x2['count']/10, 0)
x2
#Testing x2
x2
hm_df = pd.pivot_table(x2, index= 'Age', columns= 'Area Name', values='count')
hm_df
#Heatmap Visualization
import seaborn as sns
from matplotlib.ticker import FuncFormatter
fig = plt.figure(figsize=(18,10))
ax = fig.add_subplot(1, 1, 1)
comma_fmt = FuncFormatter(lambda x, p: format(int(x), ','))
ax = sns.heatmap(hm_df, linewidth = 0.2, annot = True, cmap = 'coolwarm', fmt=',.0f',
square = True, annot_kws={'size' : 1},
cbar=False)
plt.title('Heatmap- Citations by Age Group in each Neighborhood')
plt.xlabel('Neighborhood', fontsize=20)
plt.ylabel('Age', fontsize=20)
plt.yticks(rotation=0, size=6)
plt.xticks(size=5)
plt.show()
### Tab 3
This stacked bar graph shows the total amount of people arrested per age group, along with the breakdown between male and female. This chart aims to give more detail into the amount of people arrested per age group in all of LA, as well as their genders.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
filename = 'Arrest_Data_from_2020_to_Present.csv'
df = pd.read_csv(filename)
print(df.columns)
stacked_df = df.groupby(['Age', 'Sex Code'])['Age'].count().reset_index(name='count')
stacked_df = stacked_df.pivot(index='Age', columns='Sex Code', values='count')
stacked_df
fig = plt.figure(figsize=(18, 10))
ax = fig.add_subplot(1, 1, 1)
stacked_df.plot(kind='bar', stacked=True, ax=ax)
plt.ylabel('Total Arrests', fontsize=18, labelpad=10)
plt.title('Total Arrests by Age and Gender', fontsize=18)
plt.yticks(fontsize=12)
plt.xticks(rotation=60, fontsize=6)
plt.show()
This bar graph displays the total amount of arrests for the top 20 offenses. The previous visualizations showed the age and neighborhood of citizens arrested, so this visualization aims to show what these individuals are commonly arrested for.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
filename = 'Arrest_Data_from_2020_to_Present.csv'
df = pd.read_csv(filename, nrows=5)
print(df.columns)
df = pd.read_csv(filename, usecols = ['Sex Code', 'Charge Description', 'Arrest Date'])
df
#Testing data
df.dtypes
df.isna().sum()
df['Arrest Date'] = pd.to_datetime(df['Arrest Date'], format='%m/%d/%Y %I:%M:%S %p')
df
#Setting up chart
y = df.groupby(['Sex Code', 'Charge Description']).size().reset_index(name='count')
y.columns = ['Precinct', 'Offense', 'Total Arrests']
y.columns = ['Gender', 'Offense', 'Total Arrests']
y = y.sort_values('Total Arrests', ascending=False)
y.reset_index(inplace=True, drop=True)
y
#Chart displays the offenses which carried the most arrests.
plt.figure(figsize=(18, 10))
plt.bar(y.loc[0:19, 'Offense'], y.loc[0:19, 'Total Arrests'], label='Arrest Count')
plt.xticks(rotation=45, fontsize= 6, ha="right")
plt.legend(loc='upper right')
plt.title('Top 20 Offenses by Total Arrests')
plt.ylabel('Total Arrests')
plt.xlabel('Offense')
plt.show()
### Tab 5
This multiple line plot displays the amount of arrests per hour for each weekday. The previous visualizations display who is arrested and for what offenses, so this visualization shows at what time arrests commonly occur.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
df = pd.read_csv(filename)
print(df.columns)
filename = 'Arrest_Data_from_2020_to_Present.csv'
#Note: Stack Overflow and other online resources assited with this section. There may be a more efficient/streamlined way to do the following, but this is what worked for me.
#Note: The dataset included a date column and a time column formatted as HHMM, which had to be adjusted.
# Change 'Arrest Date' to just the date (Arrest Date included 12:00am for each arrest, which is incorrect. The time column includes the correct arrest time)
df['Arrest Date'] = pd.to_datetime(df['Arrest Date']).dt.date
# Reformatting HHMM from 'Time' column to only gather hours
df['Time'] = df['Time'].fillna(0).astype(int).astype(str).str.zfill(4)
df['Time'] = df['Time'].replace({'2400': '0000'})
df['Hour'] = df['Time'].str[:2]
df['Date'] = pd.to_datetime(df['Arrest Date'])
# Changing day of week from Integer to actual name
df['WeekDay'] = df['Date'].dt.dayofweek
day_map = {0: 'Monday', 1: 'Tuesday', 2: 'Wednesday', 3: 'Thursday', 4: 'Friday', 5: 'Saturday', 6: 'Sunday'}
df['WeekDay'] = df['WeekDay'].map(day_map)
#Group by day of the week name and hour to count occurrences
arrests_per_hour_and_day = df.groupby(['WeekDay', 'Hour']).size().reset_index(name='Total Arrests')
#Sorting
arrests_per_hour_and_day['WeekDay'] = pd.Categorical(arrests_per_hour_and_day['WeekDay'], categories=day_map.values(), ordered=True)
arrests_per_hour_and_day.sort_values(by=['WeekDay', 'Hour'], inplace=True)
arrests_per_hour_and_day
import matplotlib.pyplot as plt
import pandas as pd
fig = plt.figure(figsize=(18, 10))
ax = fig.add_subplot(1, 1, 1)
# Define a color map if you want distinct colors for each day
colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
day_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
for (key, grp), color in zip(arrests_per_hour_and_day.groupby(['WeekDay']), colors):
grp.plot(ax=ax, kind='line', x='Hour', y='Total Arrests', label=key, color=color, marker='8')
# Set plot labels and title
ax.set_xlabel('Hour of the Day')
ax.set_ylabel('Total Arrests')
ax.set_title('Total Arrests by Hour')
ax.tick_params(axis='x', labelsize=14, rotation=0)
ax.tick_params(axis='y', labelsize=14, rotation=0)
ax.legend(title='WeekDay')
ax.set_xticks(np.arange(24))
plt.show()