I have a dataset that looks like the following:
library(tidyverse)
library(sf)
library(giscoR)
temp <- data.frame(Country = c("United States", "Brazil", "Mexico", "Canada", "Argentina", "Chile",
"Peru", "Guatemala", 'Ecuador', "United Kingdom"),
Count = c(3000000, 300000, 250000, 135000, 100000, 99000, 98000, 47000, 40000, 39000))
and I'm able to successfully generate a map using the following code:
all_countries <- gisco_get_countries()
symbol_pos <- st_centroid(all_countries, of_largest_polygon = TRUE)
temp2 <- temp %>%
left_join(symbol_pos, by=c("Country" = "NAME_ENGL")) %>%
arrange(desc(Count))
ggplot() +
geom_sf(data = all_countries, fill = "white") +
geom_sf(data = temp2, pch = 21, mapping = aes(size = Count, geometry = geometry, fill = Count)) +
scale_size( range = c(1, 20), guide = guide_legend(direction = "horizontal", nrow = 1, label.position = "bottom")) +
scale_fill_gradientn(colours = hcl.colors(10, "Blues 3", rev = TRUE, alpha = 0.9)) +
guides(fill = guide_legend(title = "")) +
theme_void() +
theme(legend.position = "bottom")
My main issue is that the US number is so much larger than everything else that all other points are much smaller and basically white. I'd really like a visualization where I can have a layer with the same exact code, but removing the US observation, and then another layer with the US observation but in Red with a size roughly the same as the next biggest. Brazil. So it would look like the following (but with a red circle on US)
tempNoUS <- temp2 %>%
filter(Country != "United States")
ggplot() +
geom_sf(data = all_countries, fill = "white") +
geom_sf(data = tempNoUS, pch = 21, mapping = aes(size = Count, geometry = geometry, fill = Count)) +
scale_size( range = c(1, 20), guide = guide_legend(direction = "horizontal", nrow = 1, label.position = "bottom")) +
scale_fill_gradientn(colours = hcl.colors(10, "Blues 3", rev = TRUE, alpha = 0.9)) +
guides(fill = guide_legend(title = "")) +
theme_void() +
theme(legend.position = "bottom")
I looked at library(ggnewscale)
to see if I could add the following lines as part of my testing:
+ new_scale("color") +
geom_sf(data =temp2 %>% filter(Country == "United States"), pch = 21, mapping = aes(size = Count, geometry = geometry, fill = Count))
and it didnt seem to really do anything.
To summarize, I'd like two geom_sf()
layers, one for non-US countries with a scale_fill_gradientn
of Blue3, and then the other layer just for the US with a fill of Red.
Is this what you're looking for?
ggplot() +
geom_sf(data = all_countries, fill = "white") +
geom_sf(data = tempNoUS, pch = 21, mapping = aes(size = Count, geometry = geometry, fill = Count)) +
scale_size(range = c(1, 20), guide = guide_legend(direction = "horizontal", nrow = 1, label.position = "bottom")) +
scale_fill_gradientn(colours = hcl.colors(10, "Blues 3", rev = TRUE, alpha = 0.9)) +
guides(fill = guide_legend(title = "")) +
new_scale("fill") +
new_scale("size") +
geom_sf(data =temp2 %>%
filter(Country == "United States"), pch = 21,
mapping = aes(size = Count, geometry = geometry, fill = Count)) +
scale_fill_gradientn(colours = c("red")) +
scale_size(range = c(1, 20)) +
theme_void() +
theme(legend.position = "right")
You might need to play around with legend sizes, scale limits to get exactly what you want. It does also sound as though doing something like a log transform on the count might b appropriate and then you wouldn't need to split the data.