在 ggplot2/ggmap 上为不同的图形系列设置固定比例
setting a fixed scale for distinct graphic series on ggplot2/ggmap
我制作了一系列每月发病率的地图。这个想法是制作一个gif。
问题是每个地块都是用自己的比例独立创建的。
在这种情况下,我使用的是 viridis。是否有某种方法可以使所有地块保持相同的比例和范围,即使特定月份(一个地块)在这些比例上没有数据?
这是我做的:
library(ggmap)
library(sp)
murder <- subset(crime, offense == "murder")
murder <- SpatialPointsDataFrame(murder[,c("lon", "lat")], data=murder,
proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
p <- ggmap(get_stamenmap(bbox=c(left=min(murder$lon), bottom=min(murder$lat),
right=max(murder$lon), top=max(murder$lat)), zoom=12))
d <- unique(murder$month)
murder <- murder[!(murder$month=="january" & murder$hour>0 & murder$hour<17),]
murder <- murder[!(murder$month=="february" & murder$hour>110 & murder$hour<24),]
murder <- murder[!(murder$month=="march" & murder$hour>12 & murder$hour<17),]
for (i in d){
murder2 <- murder[murder$month==i,]
mapa <- p +
geom_point(data=murder2@data,
aes(x=murder2@coords[,1], y=murder2@coords[,2], color=as.numeric(hour)),
alpha=0.5,size=7) +
scale_color_viridis_c(option="C",breaks=c(0,2,4,8,12,16,20,23),
labels=c("00:00","02:00", "04:00","08:00","12:00","16:00","20:00","23:00"),
name="Hour",
guide=guide_legend( keyheight = unit(3, units = "mm"),
keywidth=unit(6, units = "mm"),
label.position = "bottom", title.position = 'top', nrow=1,
label.theme=element_text(size = 6,face = "bold",color = "grey2",family = "Gotham"),
title.theme=element_text(size = 6,face = "bold",color = "grey2",family = "Gotham", hjust=0.5)
))
ggsave(filename=paste0(i,".png"),plot=mapa, bg="transparent",
width =15, height = 15, units="cm", dpi=200)
}
这些是我的结果。第一个图(从 3 月开始)有 8 个值,而第二个图(从 2 月开始)只有 2:
我希望每张地图都具有相同的 8 个值。即使在这些值内没有观测值。
尝试用以下代码替换 for 循环中的代码。评论中的解释:
# there's lat / lon info in the data file, no need to reference coords separately
murder2 <- murder[murder$month==i, ]@data
# define hour as a factor here, with the same ranges & labels, for each loop
murder2$hour <- cut(murder2$hour,
breaks = c(0, 2, 4, 8, 12, 16, 20, 23, 25),
labels = c("00:00", "02:00", "04:00", "08:00",
"12:00", "16:00", "20:00", "23:00"),
right = FALSE)
mapa <- p +
geom_point(data = murder2,
aes(x = lon, y = lat, color = hour)) +
scale_color_viridis_d(option = "C",
name = "Hour",
drop = FALSE, # keeps unused levels in the legend
guide = guide_legend(keyheight = unit(3, units = "mm"),
keywidth = unit(6, units = "mm"),
label.position = "bottom",
title.position = 'top',
nrow = 1,
label.theme = element_text(size = 6, face = "bold",
color = "grey2",
family = "Gotham"),
title.theme = element_text(size = 6, face = "bold",
color = "grey2",
family = "Gotham",
hjust=0.5)))
ggsave(filename = paste0(i,".png"), plot = mapa, bg = "transparent",
width = 15, height = 15, units="cm", dpi = 200)
另外,如果最终目标是制作动画 gif,您可能希望改用 gganimate 包。它自动执行了在不同状态之间转换所涉及的大量工作。
我制作了一系列每月发病率的地图。这个想法是制作一个gif。 问题是每个地块都是用自己的比例独立创建的。 在这种情况下,我使用的是 viridis。是否有某种方法可以使所有地块保持相同的比例和范围,即使特定月份(一个地块)在这些比例上没有数据?
这是我做的:
library(ggmap)
library(sp)
murder <- subset(crime, offense == "murder")
murder <- SpatialPointsDataFrame(murder[,c("lon", "lat")], data=murder,
proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
p <- ggmap(get_stamenmap(bbox=c(left=min(murder$lon), bottom=min(murder$lat),
right=max(murder$lon), top=max(murder$lat)), zoom=12))
d <- unique(murder$month)
murder <- murder[!(murder$month=="january" & murder$hour>0 & murder$hour<17),]
murder <- murder[!(murder$month=="february" & murder$hour>110 & murder$hour<24),]
murder <- murder[!(murder$month=="march" & murder$hour>12 & murder$hour<17),]
for (i in d){
murder2 <- murder[murder$month==i,]
mapa <- p +
geom_point(data=murder2@data,
aes(x=murder2@coords[,1], y=murder2@coords[,2], color=as.numeric(hour)),
alpha=0.5,size=7) +
scale_color_viridis_c(option="C",breaks=c(0,2,4,8,12,16,20,23),
labels=c("00:00","02:00", "04:00","08:00","12:00","16:00","20:00","23:00"),
name="Hour",
guide=guide_legend( keyheight = unit(3, units = "mm"),
keywidth=unit(6, units = "mm"),
label.position = "bottom", title.position = 'top', nrow=1,
label.theme=element_text(size = 6,face = "bold",color = "grey2",family = "Gotham"),
title.theme=element_text(size = 6,face = "bold",color = "grey2",family = "Gotham", hjust=0.5)
))
ggsave(filename=paste0(i,".png"),plot=mapa, bg="transparent",
width =15, height = 15, units="cm", dpi=200)
}
这些是我的结果。第一个图(从 3 月开始)有 8 个值,而第二个图(从 2 月开始)只有 2:
我希望每张地图都具有相同的 8 个值。即使在这些值内没有观测值。
尝试用以下代码替换 for 循环中的代码。评论中的解释:
# there's lat / lon info in the data file, no need to reference coords separately
murder2 <- murder[murder$month==i, ]@data
# define hour as a factor here, with the same ranges & labels, for each loop
murder2$hour <- cut(murder2$hour,
breaks = c(0, 2, 4, 8, 12, 16, 20, 23, 25),
labels = c("00:00", "02:00", "04:00", "08:00",
"12:00", "16:00", "20:00", "23:00"),
right = FALSE)
mapa <- p +
geom_point(data = murder2,
aes(x = lon, y = lat, color = hour)) +
scale_color_viridis_d(option = "C",
name = "Hour",
drop = FALSE, # keeps unused levels in the legend
guide = guide_legend(keyheight = unit(3, units = "mm"),
keywidth = unit(6, units = "mm"),
label.position = "bottom",
title.position = 'top',
nrow = 1,
label.theme = element_text(size = 6, face = "bold",
color = "grey2",
family = "Gotham"),
title.theme = element_text(size = 6, face = "bold",
color = "grey2",
family = "Gotham",
hjust=0.5)))
ggsave(filename = paste0(i,".png"), plot = mapa, bg = "transparent",
width = 15, height = 15, units="cm", dpi = 200)
另外,如果最终目标是制作动画 gif,您可能希望改用 gganimate 包。它自动执行了在不同状态之间转换所涉及的大量工作。