I have two data sets with three variables. I want to show one of them as a heatmap and two as a pie chart, on a world map.
I used the below code but got an error. I would like to know how I can solve it.
library(ggplot2)
library(scatterpie)
world_map <- map_data("world")
df <- data.frame(Country = c("USA", "Canada", "Mexico"),
Cases = c(10, 20, 30))
df_piechart <- data.frame(long = c(-95, -110, -75),
lat = c(37, 60, 20),
size = c(5, 10, 15),
Group1 = c(20, 30, 50),
Group2 = c(30, 40, 30))
ggplot() +
geom_map(dat = world_map, map = world_map, aes(map_id = region), color = "white", fill = "#d3d4d3", linewidth = 0.5, alpha=0.4 ) +
geom_map(dat = df, map = world_map, aes(map_id = Country, fill = Cases), linewidth = 0.5) +
scale_fill_gradient(low = "skyblue", high = "dodgerblue4", name = "Avian Cases") +
geom_map(dat = world_map, map = world_map, aes(map_id = region), color = "white", fill = "#d3d4d3", linewidth = 0.5, alpha=0.0 ) +
expand_limits(x = world_map$long, y = world_map$lat) +
geom_scatterpie(data = df_piechart, aes(x = long, y = lat, r = size),
cols = colnames(df_piechart[, c(4:5)]), alpha = 0.8) +
theme(legend.text = element_text(size = 8, family = "serif"),
legend.title = element_text(size = 8, face = "bold", family = "serif"),
legend.key.height = unit(0.2, 'cm'),
legend.key.width = unit(0.2, 'cm')) +
theme_void()
error:
Error in `train_discrete()`:
! Continuous value supplied to a discrete scale
The use of (dynamic) fill=
in other layer's aesthetics is breaking geom_scatterpie
. This was discussed in 2021 at https://github.com/ericpante/marmap/issues/20#issuecomment-796591190, noting
The error comes from a conflict between the fill colour palette you provide for the tiles of the base map (here, this is a continuous variable: for each depth value, a colour is associated), and the fill colour used for the pie charts (here, this is a discrete variable: for each level of your factor, Legal or Illegal, a fill colour is used).
(Note that the author of that issue cross-posted the same problem to multiple packages, so this comment I linked is in a different package. The author of scatterpie
linked to that issue in scatterpie#31.)
Two options: (1) drop your desired fill=
aesthetics, or (2) add ggnewscale::add_scale_fill()
and continue to use your existing code.
Remove fill=Cases
in the second geom_map
and scale_fill_gradient
then you can plot it (though perhaps not with what you want):
gg <- ggplot() +
geom_map(dat = world_map, map = world_map, aes(map_id = region), color = "white", fill = "#d3d4d3", linewidth = 0.5, alpha=0.4 ) +
geom_map(dat = df, map = world_map, aes(map_id = Country), linewidth = 0.5) + # , fill = Cases
# scale_fill_gradient(low = "skyblue", high = "dodgerblue4", name = "Avian Cases") +
geom_map(dat = world_map, map = world_map, aes(map_id = region), color = "white", fill = "#d3d4d3", linewidth = 0.5, alpha=0.0 ) +
expand_limits(x = world_map$long, y = world_map$lat) +
geom_scatterpie(data = df_piechart, aes(x = long, y = lat, r = size),
cols = colnames(df_piechart[, c(4:5)]), alpha = 0.8) +
theme(legend.text = element_text(size = 8, family = "serif"),
legend.title = element_text(size = 8, face = "bold", family = "serif"),
legend.key.height = unit(0.2, 'cm'),
legend.key.width = unit(0.2, 'cm')) +
theme_void()
gg
Use ggnewscale
(or some other package that allows you to have multiple color scales) and use add_new_fill()
, as in
gg <- ggplot() +
geom_map(dat = world_map, map = world_map, aes(map_id = region), color = "white", fill = "#d3d4d3", linewidth = 0.5, alpha=0.4 ) +
geom_map(dat = df, map = world_map, aes(map_id = Country, fill = Cases), linewidth = 0.5) +
scale_fill_gradient(low = "skyblue", high = "dodgerblue4", name = "Avian Cases") +
ggnewscale::new_scale_fill() +
geom_map(dat = world_map, map = world_map, aes(map_id = region), color = "white", fill = "#d3d4d3", linewidth = 0.5, alpha=0.0 ) +
expand_limits(x = world_map$long, y = world_map$lat) +
geom_scatterpie(data = df_piechart, aes(x = long, y = lat, r = size),
cols = colnames(df_piechart[, c(4:5)]), alpha = 0.8) +
theme(legend.text = element_text(size = 8, family = "serif"),
legend.title = element_text(size = 8, face = "bold", family = "serif"),
legend.key.height = unit(0.2, 'cm'),
legend.key.width = unit(0.2, 'cm')) +
theme_void()
gg
Side note, you should add coord_quickmap()
so that the correct ratio is preserved,
gg + coord_quickmap()