library(tidyverse)
library(ggplot2)
library(plotly)
library(kableExtra)
library(here)
library(leaflet)

# Homicide Data ----

## Pre 940
load(file = here("data-outputs", "WA2015.rda"))
homicides.pre940 <- finalmerge_2015 %>% 
  filter(homicide == 1 & date < "2018-12-07") %>%
  arrange(date)

## Post 940
load(file = here::here("data-outputs", "WA940.rda"))
last.data.update = max(last.fe.date, last.wapo.date)
homicides.post940 <- finalmerge_940 %>% 
  filter(homicide==1) %>%
  arrange(date)


# County popsizes ----
load(file = here("data-outputs", "pop_wacounty_2015-20.rda"))

# Make county popdata ----

## We calculate averages of the pre and post populations

tmp <- (wapop_2015[, 3:14] + wapop_2016[, 3:14] 
        + wapop_2017[, 3:14] + wapop_2018[, 3:14])/4 

pop_pre <- bind_cols(wapop_2015[, 1:2], tmp)

tmp <- (wapop_2019[, 3:14] + wapop_2020[, 3:14])/2 

pop_post <- bind_cols(wapop_2015[, 1:2], tmp)


# Make homicide data ----
  
#Kevin Peterson, Carlos Hunter, Jenoah Donald are Black; Clayton Joseph and Kfin Karuo are pacific Islander.

homPre_county <- homicides.pre940 %>%
  mutate(race = case_when(
    name == "Carlos Markein Hunter" ~ "BAA",
    name == "Kfin Karuo" ~ "API",
    TRUE ~ as.character(raceImp)
  )) %>%
  group_by(county) %>% 
  summarize(hom = n(),
            hom.black = sum(ifelse(race == "BAA", 1, 0)),
            hom.bipoc = sum(ifelse(race != "WEA", 1, 0)),
            pd = sum(ifelse(grepl("Police", agency.type), 1, 0)),
            so = sum(ifelse(grepl("Sheriff", agency.type), 1, 0))
            ) %>%
  mutate(pct.black = 100*round(hom.black/hom,3),
         pct.bipoc = 100*round(hom.bipoc/hom, 3),
         pct.pd = 100*round(pd/hom,3),
         pct.so = 100*round(so/hom, 3)
         )

homPost_county <- homicides.post940 %>%
  mutate(race = case_when(
    name == "Carlos Markein Hunter" ~ "BAA",
    name == "Kfin Karuo" ~ "API",
    TRUE ~ as.character(raceImp)
  )) %>%
  group_by(county) %>% 
  summarize(hom = n(),
            hom.black = sum(ifelse(race == "BAA", 1, 0)),
            hom.bipoc = sum(ifelse(race != "WEA", 1, 0)),
            pd = sum(ifelse(grepl("Police", agency.type), 1, 0)),
            so = sum(ifelse(grepl("Sheriff", agency.type), 1, 0))
            ) %>%
  mutate(pct.black = 100*round(hom.black/hom,3),
         pct.bipoc = 100*round(hom.bipoc/hom, 3),
         pct.pd = 100*round(pd/hom,3),
         pct.so = 100*round(so/hom, 3)
         )

# Merge the homicides with the county popdata ----

df_pre <- pop_pre %>%
  left_join(homPre_county) 

df_post <- pop_post %>%
  left_join(homPost_county)

## some counties don't have any cases
df_pre[is.na(df_pre)] = 0
df_post[is.na(df_post)] = 0

yrsPre <- as.numeric(as.Date("2018-12-05") - as.Date("2015-01-01"))/365
yrsPost <- as.numeric(Sys.Date() - as.Date("2018-12-06"))/365
  
df_pre <- df_pre %>%  
  mutate(risk = round(100000*hom/TOT/yrsPre, 2),
         risk.black = round(100000*hom.black/B/yrsPre, 2),
         risk.bipoc = round(100000*hom.bipoc/BIPOC/yrsPre, 2),
         period = "pre"
         )

df_post <- df_post %>%  
  mutate(risk = round(100000*hom/TOT/yrsPost, 2),
         risk.black = round(100000*hom.black/B/yrsPost, 2),
         risk.bipoc = round(100000*hom.bipoc/BIPOC/yrsPost, 2),
         period = "post")

## Long and wide data ----

counties.l <- bind_rows(df_pre, df_post) %>%
  select(county, period, pop.tot=TOT, pop.black=B, pop.bipoc=BIPOC, 
         hom, hom.black, hom.bipoc, 
         pct.black, pct.bipoc, 
         risk, risk.black, risk.bipoc, 
         pct.pd, pct.so)

counties.w <- pivot_wider(data=counties.l, 
                          id_cols = county,
                          names_from = period,
                          values_from = pop.tot:pct.so)

# Plotting setup for subtitles with plotly

m <- list(
    l = 80,
    r = 80,
    b = 80,
    t = 80,
    pad = 0
  )

Introduction

This report examines the number and rate of persons killed by police by county in WA State, before and after the passage of I-940. The before period spans Jan 1, 2015 - Dec 6, 2018, and the after period spans from Dec 7, 2018 to the current date (2021-11-13).


Data

There are two types of data used for this report:

  • Population Estimates: US Census estimates by county, broken down by age, race and sex.

    Age – We use the population counts for the 15-69 year old population, as this is the age range at risk of being killed by police. Only 4 of the persons killed by police since 2015 were older, and none were younger.

    Black race – We calculate estimates of the Black population in each county using the Census race category “Non-Hispanic Black Alone or in Combination”. This excludes persons who identify as Hispanic ethnicity and Black race, but includes non-Hispanics who identify with multiple races, as long as Black is one of those.

    BIPOC race – These estimates are calculated as the total population minus the census category “non-Hispanic White Alone”.

    Pre and Post estimates – We take the average population count for the 4 years in the pre-period, 2015-2018, and the average count in 2 years in the post period, 2019-2020. We do not have county-level population estimates for 2021 yet, so these are not included in the post-period average.

  • Persons killed by police since I-940: Merged data from the Fatal Encounters Project and the Washington Post Police Shootings Database

    Homicides by police – We filter out all cases from the Fatal Encounters data where the circumstances are coded as “Suicide”. For the post-period, we select cases after December 6, 2018, the date the I-940 bill was passed into law. For the pre-period, we select cases from Jan 1, 2015 to Dec 6, 2018.

    Race – These two datasets use a combined race/ethnicity coding scheme, where Hispanic is treated as a racial category, and no multiple race options are allowed. We use the race imputations from the Fatal Encounters dataset where possible when race is unknown (12 cases in the 940 data, all of which are imputed to be white; 26 cases in the 2015 data, 20 imputed to be white). Black cases are simply those identified as Black/African American, and BIPOC is all cases other than White/European American.


Metrics

In addition to the raw number of persons killed, we use three additional metrics:

  • The percent of persons killed who are Black, or BIPOC

  • The annual population-adjusted risk of being killed per 100,000 residents, overall, and by race.

  • The percent of the homicides that are committed by local police, and the percent committed by county Sheriff’s deputies.

The graphs show the rankings of each county using each of these metrics.


Population and demographics

There are 2 plots in each tab: Pre-940 population, and percent change in the post-940 period.

In the change plots, the red horizontal line highlights the value 0, indicating no change.

Total Population

Pre-940

p <- ggplot(data = counties.l %>% filter(period == "pre"),
            aes(x=pop.tot, y=reorder(county, pop.tot), 
                text=paste(county, "<br>",
                           "Population: ", 
                           scales::comma(pop.tot)))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  
  scale_x_continuous(labels = scales::comma) +
  
  theme(axis.text.y=element_text(size=rel(0.6)),
        legend.position = "none") +
  labs(x="Population",
       y="County")
  
ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('County Populations Pre-940',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

Change: Pre vs. Post

df <- counties.w %>% 
  select(county, pop.tot_pre, pop.tot_post) %>%
  mutate(pop_pctchange = (pop.tot_post - pop.tot_pre)/pop.tot_pre)

p <- ggplot(data = df,
            aes(x=pop.tot_pre, y=pop_pctchange, 
                text=paste(county, "<br>",
                           "pre:", scales::comma(pop.tot_pre), "<br>",
                           "post:", scales::comma(pop.tot_post), "<br>"))) +
  geom_point(shape=21, fill="lightsteelblue")  +
  geom_hline(yintercept=0, color="red") +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(x="Pre-940 county population",
       y="Change post-940 (difference in %)")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('County Population Change by Pre-940 Size',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

Black Population

Pre-940

p <- ggplot(data = counties.l %>% 
              filter(period == "pre") %>%
              mutate(pop.pct.black = 100*pop.black/pop.tot),
            aes(x=pop.pct.black, y=reorder(county, pop.pct.black), 
                text=paste(county, "<br>",
                           scales::number(pop.pct.black, acc=0.1, suffix="%"), 
                           "Black"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  theme(axis.text.y=element_text(size=rel(0.6)),
        legend.position = "none") +
  
  scale_x_continuous(labels = scales::number_format(acc=0.1, suffix="%")) +
  
  labs(x="Black Population (%)",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Population Percent Black: Pre-940',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

Change: Pre vs. Post

df <- counties.l %>% 
  select(county, pop.tot, pop.black, period) %>%
  mutate(pop.pct.black = 100*pop.black/pop.tot) %>%
  pivot_wider(id_cols = county, 
              names_from = period, 
              values_from = pop.pct.black) %>%
  mutate(pctchange.black = post - pre)

p <- ggplot(data = df,
            aes(x=pre, y=pctchange.black, 
                text=paste(county, "<br>",
                           "pre:", 
                           scales::number(pre, acc = 0.1, suffix = "%"), "<br>",
                           "post:", 
                           scales::number(post, acc = 0.1, suffix = "%"), "<br>"))) +
  geom_point(shape=21, fill="lightsteelblue")  +
  geom_hline(yintercept=0, color="red") +
  
  scale_x_continuous(labels = scales::number_format(acc = 0.1, suffix="%")) +
  scale_y_continuous(labels = scales::number_format(acc = 0.1, suffix="%")) +
  
  labs(x="Black population pre-940 (%)",
       y="Change post-940 (difference in %)")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Black Population Change by Pre-940 Percent',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

BIPOC Population

Pre-940

p <- ggplot(data = counties.l %>% 
              filter(period == "pre") %>%
              mutate(pop.pct.bipoc = 100*pop.bipoc/pop.tot),
            aes(x=pop.pct.bipoc, y=reorder(county, pop.pct.bipoc), 
                text=paste(county, "<br>",
                           scales::number(pop.pct.bipoc, acc=0.1, suffix="%"), 
                           "BIPOC"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  theme(axis.text.y=element_text(size=rel(0.6)),
        legend.position = "none") +
  
  scale_x_continuous(labels = scales::number_format(acc=0.1, suffix="%")) +
  
  labs(x="BIPOC Population (%)",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Population Percent BIPOC: Pre-940',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

Change: Pre vs. Post

df <- counties.l %>% 
  select(county, pop.tot, pop.bipoc, period) %>%
  mutate(pop.pct.bipoc = 100*pop.bipoc/pop.tot) %>%
  pivot_wider(id_cols = county, 
              names_from = period, 
              values_from = pop.pct.bipoc) %>%
  mutate(pctchange.bipoc = post - pre)

p <- ggplot(data = df,
            aes(x=pre, y=pctchange.bipoc, 
                text=paste(county, "<br>",
                           "pre:", 
                           scales::number(pre, acc = 0.1, suffix = "%"), "<br>",
                           "post:", 
                           scales::number(post, acc = 0.1, suffix = "%"), "<br>"))) +
  geom_point(shape=21, fill="lightsteelblue")  +
  geom_hline(yintercept=0, color="red") +
  
  scale_x_continuous(labels = scales::number_format(acc = 0.1, suffix="%")) +
  scale_y_continuous(labels = scales::number_format(acc = 0.1, suffix="%")) +
  
  labs(x="BIPOC population pre-940 (%)",
       y="Change post-940 (difference in %)")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('BIPOC Population Change by Pre-940 Percent',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

People killed by police

In this section, most tabs will have 3 plots: Pre-940, post-940 and change.

  • The pre and post-940 plots will include all counties, if that makes sense for that metric (number and risk), or be restricted to the counties that have at least one person killed by police during that period (percent Black or BIPOC killed, percent killed by police officers or sheriff’s deputies).

  • The change plots graph the pre-940 vs. post-940 values. The red line again highlights the “no change” values, but now this line will be at a 45 degree angle. Points above the line indicate higher values for the post-940 period; points below the line indicate higher values in the pre-940 period.

Number

We don’t include a change plot here because the lengths of the pre and post-940 periods are not the same, so the raw number of persons killed will not be comparable. For a time and population adjusted comparison pre/post please see the Risk tab.

Pre 940

p <- ggplot(data = counties.l %>% 
              filter(period == "pre"),
            aes(x=hom, y=reorder(county, hom), 
                text=paste(county, "<br>",
                           hom, "persons killed"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +

  theme(axis.text.y=element_text(size=rel(0.6)),
        legend.position = "none") +
  labs(x="Number killed",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Number of persons killed by police: Pre 940',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% 
              filter(period == "post"),
            aes(x=hom, y=reorder(county, hom), 
                text=paste(county, "<br>",
                           hom, "persons killed"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  theme(axis.text.y=element_text(size=rel(0.6)),
        legend.position = "none") +
  labs(x="Number killed",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Number of persons killed by police: Post 940',
                    '<br>',
                    '<sup>',
                    'Includes all counties',
                    '</sup>'),
      x=0.09),
      margin=m)

Pct Black

Pre 940

max <- ceiling(max(counties.l$pct.black))


p <- ggplot(data = counties.l %>% 
              filter(period == "pre" & hom > 0),
            aes(x=pct.black, y=reorder(county, pct.black), 
                text=paste(county, "<br>",
                           scales::number(pct.black, suffix="%"), "Black"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  
  labs(x="Percent of persons killed",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Black persons killed by police: Pre 940',
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% 
              filter(period == "post" & hom > 0),
            aes(x=pct.black, y=reorder(county, pct.black), 
                text=paste(county, "<br>",
                           scales::number(pct.black, suffix="%"), "Black"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  labs(x="Percent",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Percent of persons killed by police who are Black: Post 940',
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Change

p <- ggplot(data = counties.w %>%
              filter(hom_pre > 0 & hom_post > 0),
            aes(x=pct.black_pre, y=pct.black_post, 
                text=paste(county, "<br>",
                           "Pre 940:", 
                           scales::number(pct.black_pre, suffix="%"), "<br>",
                           "Post 940:", 
                           scales::number(pct.black_post, suffix="%")))) +
  geom_jitter(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=0, slope=1, color="red") +
  
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(-3,max)) +
  scale_y_continuous(labels = scales::number_format(suffix="%"), limits = c(-3,max)) +

  labs(x="Percent pre-940",
       y="Percent post-940")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Change in percent of persons killed who are Black',
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement both periods',
                    '</sup>'),
      x=0.09),
      margin=m)

Pct BIPOC

Pre 940

max <- ceiling(max(counties.l$pct.bipoc))


p <- ggplot(data = counties.l %>% 
              filter(period == "pre" & hom > 0),
            aes(x=pct.bipoc, y=reorder(county, pct.bipoc), 
                text=paste(county, "<br>",
                           scales::number(pct.bipoc, suffix="%"), "BIPOC"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  
  labs(x="Percent of persons killed",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('BIPOC persons killed by police: Pre 940',
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% 
              filter(period == "post" & hom > 0),
            aes(x=pct.bipoc, y=reorder(county, pct.bipoc), 
                text=paste(county, "<br>",
                           scales::number(pct.bipoc, suffix="%"), "BIPOC"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  labs(x="Percent",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Percent of persons killed by police who are BIPOC: Post 940',
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Change

p <- ggplot(data = counties.w %>%
              filter(hom_pre > 0 & hom_post > 0),
            aes(x=pct.bipoc_pre, y=pct.bipoc_post, 
                text=paste(county, "<br>",
                           "Pre 940:", 
                           scales::number(pct.bipoc_pre, suffix="%"), "<br>",
                           "Post 940:", 
                           scales::number(pct.bipoc_post, suffix="%")))) +
  geom_jitter(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=0, slope=1, color="red") +
  
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(-3,max+3)) +
  scale_y_continuous(labels = scales::number_format(suffix="%"), limits = c(-3,max+3)) +

  labs(x="Percent pre-940",
       y="Percent post-940")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Change in percent of persons killed who are BIPOC',
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement both periods',
                    '</sup>'),
      x=0.09),
      margin=m)

Risk per 100K

We use a consistent set of limits on the x-axis to facilitate visual comparison across total, Black and BIPOC risk graphs.

Pre 940

# max risk is for Black residents
max <- max(counties.l$risk.black)

p <- ggplot(data = counties.l %>% filter(period == "pre"),
            aes(x=risk, y=reorder(county, risk), 
                text=paste(county, "<br>",
                           "risk per 100K persons:", risk))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  
  scale_x_continuous(limits = c(0, max)) +
  
  theme(axis.text.y=element_text(size=rel(0.6)), legend.position = "none") +
  labs(x="Risk per 100K residents",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Risk of being killed by police: pre-940',
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% filter(period == "post"),
            aes(x=risk, y=reorder(county, risk), 
                text=paste(county, "<br>",
                           "risk per 100K persons:", risk))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  
  scale_x_continuous(limits = c(0, max)) +
  
  theme(axis.text.y=element_text(size=rel(0.6)), legend.position = "none") +
  labs(x="Risk per 100K residents",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0('Risk of being killed by police: post-940',
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Change

p <- ggplot(data = counties.w%>%
              filter(hom_pre > 0 | hom_post > 0),
            aes(x=risk_pre, y=risk_post, 
                text=paste(county, "<br>",
                           "Pre 940:", risk_pre, "<br>",
                           "Post 940:", risk_post))) +
  geom_point(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=0, slope=1, color="red") +
  
  scale_x_continuous(limits = c(0,max)) +
  scale_y_continuous(limits = c(0,max)) +

  labs(x="Risk per 100K residents pre-940",
       y="Risk per 100K residents post-940")
  
  labs(x="Risk per 100K residents pre-940",
       y="Risk per 100K residents post-940")
## $x
## [1] "Risk per 100K residents pre-940"
## 
## $y
## [1] "Risk per 100K residents post-940"
## 
## attr(,"class")
## [1] "labels"
ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Change in risk of being killed by police",
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Risk per 100K Black

Pre 940

p <- ggplot(data = counties.l %>% filter(period == "pre"),
            aes(x=risk.black, y=reorder(county, risk.black), 
                text=paste(county, "<br>",
                           "risk.black per 100K persons:", risk.black))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  
  scale_x_continuous(limits = c(0, max)) +
  
  theme(axis.text.y=element_text(size=rel(0.6)), legend.position = "none") +
  labs(x="Risk per 100K Black residents",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Black Residents' risk of being killed by police: pre-940",
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% filter(period == "post"),
            aes(x=risk.black, y=reorder(county, risk.black), 
                text=paste(county, "<br>",
                           "risk.black per 100K persons:", risk.black))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  
  scale_x_continuous(limits = c(0, max)) +
  
  theme(axis.text.y=element_text(size=rel(0.6)), legend.position = "none") +
  labs(x="Risk per 100K Black residents",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Black Residents' risk of being killed by police: post-940",
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Change

p <- ggplot(data = counties.w%>%
              filter(hom_pre > 0 | hom_post > 0),
            aes(x=risk.black_pre, y=risk.black_post, 
                text=paste(county, "<br>",
                           "Pre 940:", risk.black_pre, "<br>",
                           "Post 940:", risk.black_post))) +
  geom_point(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=0, slope=1, color="red") +
  
  scale_x_continuous(limits = c(0,max)) +
  scale_y_continuous(limits = c(0,max)) +

  labs(x="Risk per 100K Black residents pre-940",
       y="Risk per 100K Black residents post-940")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Change in Black residents' risk of being killed by police",
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Risk per 100K BIPOC

Pre 940

p <- ggplot(data = counties.l %>% filter(period == "pre"),
            aes(x=risk.bipoc, y=reorder(county, risk.bipoc), 
                text=paste(county, "<br>",
                           "risk.bipoc per 100K persons:", risk.bipoc))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  
  scale_x_continuous(limits = c(0, max)) +
  
  theme(axis.text.y=element_text(size=rel(0.6)), legend.position = "none") +
  labs(x="Risk per 100K BIPOC residents",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("BIPOC Residents' risk of being killed by police: pre-940",
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% filter(period == "post"),
            aes(x=risk.bipoc, y=reorder(county, risk.bipoc), 
                text=paste(county, "<br>",
                           "risk.bipoc per 100K persons:", risk.bipoc))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
  
  scale_x_continuous(limits = c(0, max)) +
  
  theme(axis.text.y=element_text(size=rel(0.6)), legend.position = "none") +
  labs(x="Risk per 100K BIPOC residents",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("BIPOC Residents' risk of being killed by police: post-940",
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Change

p <- ggplot(data = counties.w%>%
              filter(hom_pre > 0 | hom_post > 0),
            aes(x=risk.bipoc_pre, y=risk.bipoc_post, 
                text=paste(county, "<br>",
                           "Pre 940:", risk.bipoc_pre, "<br>",
                           "Post 940:", risk.bipoc_post))) +
  geom_point(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=0, slope=1, color="red") +
  
  scale_x_continuous(limits = c(0,max)) +
  scale_y_continuous(limits = c(0,max)) +

  labs(x="Risk per 100K BIPOC residents pre-940",
       y="Risk per 100K BIPOC residents post-940")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Change in BIPOC residents' risk of being killed by police",
                    '<br>',
                    '<sup>',
                    'All counties included',
                    '</sup>'),
      x=0.09),
      margin=m)

Police Depts

Pre 940

max <- ceiling(max(counties.l$pct.pd))


p <- ggplot(data = counties.l %>% 
              filter(period == "pre" & hom > 0),
            aes(x=pct.pd, y=reorder(county, pct.pd), 
                text=paste(county, "<br>",
                           scales::number(pct.pd, suffix="%"), "local police"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  
  labs(x="Percent of persons killed",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Persons killed by local police officers: pre-940",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% 
              filter(period == "post" & hom > 0),
            aes(x=pct.pd, y=reorder(county, pct.pd), 
                text=paste(county, "<br>",
                           scales::number(pct.pd, suffix="%"), "local police"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  labs(x="Percent",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Persons killed by local police officers: post-940",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Change

p <- ggplot(data = counties.w %>%
              filter(hom_pre > 0 & hom_post > 0),
            aes(x=pct.pd_pre, y=pct.pd_post, 
                text=paste(county, "<br>",
                           "Pre 940:", 
                           scales::number(pct.pd_pre, suffix="%"), "<br>",
                           "Post 940:", 
                           scales::number(pct.pd_post, suffix="%")))) +
  geom_jitter(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=0, slope=1, color="red") +
  
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(NA,max)) +
  scale_y_continuous(labels = scales::number_format(suffix="%"), limits = c(NA,max)) +

  labs(x="Percent pre-940",
       y="Percent post-940")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Change in percent of persons killed by local police officers",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement in both periods',
                    '</sup>'),
      x=0.09),
      margin=m)

Sheriff Offices

Pre 940

max <- ceiling(max(counties.l$pct.so))


p <- ggplot(data = counties.l %>% 
              filter(period == "pre" & hom > 0),
            aes(x=pct.so, y=reorder(county, pct.so), 
                text=paste(county, "<br>",
                           scales::number(pct.so, suffix="%"), "county Sheriff"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  
  labs(x="Percent of persons killed",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Persons killed by county Sheriff's deputies: pre-940",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.l %>% 
              filter(period == "post" & hom > 0),
            aes(x=pct.so, y=reorder(county, pct.so), 
                text=paste(county, "<br>",
                           scales::number(pct.so, suffix="%"), "county Sheriff"))) +
  geom_bar(stat="identity", fill="lightsteelblue") +
    
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0,max)) +
  
  theme(axis.text.y=element_text(size=rel(0.8)),
        legend.position = "none") +
  labs(x="Percent",
       y="County")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Persons killed by county Sheriff's deputies: post-940",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement',
                    '</sup>'),
      x=0.09),
      margin=m)

Change

p <- ggplot(data = counties.w %>%
              filter(hom_pre > 0 & hom_post > 0),
            aes(x=pct.so_pre, y=pct.so_post, 
                text=paste(county, "<br>",
                           "Pre 940:", 
                           scales::number(pct.so_pre, suffix="%"), "<br>",
                           "Post 940:", 
                           scales::number(pct.so_post, suffix="%")))) +
  geom_jitter(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=0, slope=1, color="red") +
  
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(NA,max)) +
  scale_y_continuous(labels = scales::number_format(suffix="%"), limits = c(NA,max)) +

  labs(x="Percent pre-940",
       y="Percent post-940")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Change in percent of persons killed by county Sheriff's Deputies",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement in both periods',
                    '</sup>'),
      x=0.09),
      margin=m)

PD vs. SO

These plots directly compare the responsibility each type of agency has for the homicides committed by law enforcement in their county: local police departments vs. county Sheriff’s offices.

The red line highlights the case when all homicides are committed by either local police officers or sheriff’s deputies – the upper left corner represents the case where sheriff’s deputies are responsible for 100% of the fatalities, and as you move down the red line the share of homicides committed by local police officers rises, until it hits 100% at the lower left corner. Points off the line indicate that other law enforcement agencies are responsible for some of the homicides in that county (e.g., the Washington State Patrol, or multiple agencies).

Pre 940

p <- ggplot(data = counties.w %>%
              filter(hom_pre > 0),
            aes(x=pct.pd_pre, y=pct.so_pre, 
                text=paste(county, "<br>",
                           "PDs:", 
                           scales::number(pct.pd_pre, suffix="%"), "<br>",
                           "SOs:", 
                           scales::number(pct.so_pre, suffix="%")))) +
  
  geom_jitter(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=100, slope=-1, color="red") +
  
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0-3, 100+3)) +
  scale_y_continuous(labels = scales::number_format(suffix="%"), limits = c(0-3, 100+3)) +
  
  labs(x="Percent killed by local police officers",
       y="Percent killed by county Sheriff's departments")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Comparing percent killed by PDs vs. SOs: pre-940",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement in both periods',
                    '</sup>'),
      x=0.09),
      margin=m)

Post 940

p <- ggplot(data = counties.w %>%
              filter(hom_post > 0),
            aes(x=pct.pd_post, y=pct.so_post, 
                text=paste(county, "<br>",
                           "PDs:", 
                           scales::number(pct.pd_post, suffix="%"), "<br>",
                           "SOs:", 
                           scales::number(pct.so_post, suffix="%")))) +
  
  geom_jitter(shape=21, fill="lightsteelblue")  +
  geom_abline(intercept=100, slope=-1, color="red") +
  
  scale_x_continuous(labels = scales::number_format(suffix="%"), limits = c(0-3, 100+3)) +
  scale_y_continuous(labels = scales::number_format(suffix="%"), limits = c(0-3, 100+3)) +
  
  labs(x="Percent killed by local police officers",
       y="Percent killed by county Sheriff's departments")

ggplotly(p, tooltip = "text") %>%
  layout(
    title = list(
      text = paste0("Comparing percent killed by PDs vs. SOs: post-940",
                    '<br>',
                    '<sup>',
                    'Counties with at least one person killed by law enforcement in both periods',
                    '</sup>'),
      x=0.09),
      margin=m)