I'm trying to create a map using a gradient color scheme for fatality counts per state as a result of shootings. My dataset has all 50 states + DC, and it uses the two letter abbreviation for each state. I made a variable below that counts the number of events per state.
Using this, I'm attempting to make a map where the states with higher counts are colored in darker blues and the lower counts are lighter blues.
library(maps)
library(dplyr)
library(mapproj)
fatalities_by_state <- shootings_clean %>%
count(state)
map_data <- map_data("state")
merged_data <- merge(map_data, fatalities_by_state, by.x = "region", by.y = "state", all.x = TRUE)
ggplot() +
geom_polygon(data = merged_data,
aes(x = long, y = lat, group = group, fill = log(n)),
color = "black", size = 0.2) +
theme_classic() +
scale_fill_gradient(low = "lightblue", high = "darkblue", name = "Fatalities") +
coord_map() +
labs(title = "Fatalities by State", fill = "Log Count") +
theme(plot.title = element_text(hjust = 0.5))
However, the outcome is as follows.
How can I edit my code so the actual colors show up so the higher the fatality count is, the darker the color is, and vice versa? Is there a way I can add labels where when you hover over the state, it shows the State Name and number of Fatalities?
Thanks in advance.
Couple of issues here:
geom_sf()
Here is a full repex that addresses these issues. If you want to omit the non-contiguous states, comment below and I'll update the answer. Also, if you want to know how to create an interactive map, this should be a separate question. But you shouldn't need to post a separate question, just search for questions related to plotting sf objects using the plotly
package. There are many plotly
solutions on SO. Other options include using leaflet
or mapview
, which are relatively straightforward to use.
library(dplyr)
library(sf)
library(usmap)
library(ggplot2)
# US state data as sf object from the usmap library
map_data <- us_map() %>%
rename(state = "abbr")
# Create example fatalities data
set.seed(1)
fatalities_by_state <- data.frame(state = map_data$state,
n = sample(59:1700, 51))
# Join
merged_data <- left_join(map_data, fatalities_by_state, by = "state")
# Plot
ggplot() +
geom_sf(data = merged_data,
aes(fill = log(n)),
color = "black",
linewidth = 0.2) +
theme_classic() +
scale_fill_gradient(low = "lightblue",
high = "darkblue",
name = "Fatalities\nLog Count") +
labs(title = "Fatalities by State") +
theme(plot.title = element_text(hjust = 0.5))