使用 override.aes 大小时图例键中的 R ggplot2 空格
R ggplot2 whitespace in legend key when using override.aes for size
我最近对与 报道的相同问题感到沮丧,该问题涉及弥补 ggplot 不向图例添加 NA 填充所需的黑客攻击(如果有人知道对此的更新,请告诉我).
因此,我创建了一个类似的 hack,但在一个相当复杂的情节中,我试图同时展示几件事。该图需要将点的大小设置为较小的值,因此我需要 override.aes
在图例中有足够大的点。因为我使用了 alpha
和 colour
,所以我将两者都引入了同一个图例键。
然而,奇怪的是(至少对我而言),aes
覆盖在图例键框边距和填充之间创建了难看的空白,如带有和不带有大小 aes 覆盖的地图所示:
这是怎么发生的,我怎样才能让它消失?任何帮助将不胜感激。
这是重现此代码的代码。如前所述,我的真实情节比这更复杂,但这显示了总体思路。
## create an example using the world data
require(rworldmap)
require(rgeos)
require(ggplot2)
require(viridis)
## Load world map and subset
world <- getMap()
world <- world[!world@data$ADMIN %in% c("French Southern and Antarctic Lands",
"Heard Island and McDonald Islands",
"French Guiana"),] #NA entries for these in REGION col
world <- world[world@data$REGION == "South America",]
world@data$id = rownames(world@data)
## create example where we have NA for the fill variable
world@data$fillvar <- world@data$LAT
world@data$fillvar[round(world@data$LAT) == -9] <- NA #Peru
## create spatial data frame for plotting
polydf = ggplot2::fortify(world, region="id")
polydf <- merge(polydf, world@data, by="id")
## create arbitrary grouping variable
polydf$groupvar <- ifelse(polydf$NAME == "Bolivia", "Bolivia", "NotBolivia") # the two main classes
# simulate hack where we name the NA fill case as a new grouping level (which we will use alpha for)
polydf$groupvar[is.na(polydf$fillvar)] <- 'Removed'
polydf$groupvar <- factor(polydf$groupvar)
## create centroid points to show the grouping with points, again manual hack for NA
pointsdf <- gCentroid(world[!is.na(world@data$fillvar),],byid=TRUE)
pointsdf <- as.data.frame(pointsdf@coords)
pointsdf$groupvar <- ifelse(rownames(pointsdf)=="Bolivia","Bolivia","NotBolivia")
pointsNA <- gCentroid(world[is.na(world@data$fillvar),], byid=TRUE)
pointsNA <- as.data.frame(pointsNA@coords)
pointsNA$groupvar <- "Removed"
pointsdf <- rbind(pointsdf, pointsNA)
pointsdf$groupvar <- factor(pointsdf$groupvar)
## plot with override.aes for size
sizeover <- ggplot(polydf) + theme_bw() +
aes(long,lat,group=group) +
geom_polygon(aes(fill=fillvar, alpha=groupvar)) + # shading also for groupvar
geom_path(color="black") +
coord_equal() +
scale_fill_viridis("Fill", na.value="black") +
geom_point(inherit.aes=FALSE, data=pointsdf, aes(x=x, y=y, group=groupvar, col=groupvar), size=1) +
scale_color_manual('Alpha + colour', values=c("black","transparent","white")) +
scale_alpha_manual('Alpha + colour', values=c(0.8,0.8, 1)) +
theme(legend.key = element_rect(colour = "black"), legend.box = "vertical", legend.position = "top") +
guides(color=guide_legend(override.aes = list(size=2)),
alpha=guide_legend(override.aes = list(alpha=c(1,1,1), fill=c('white','white','black'))))
## plot without override.aes for size
nosizeover <- ggplot(polydf) + theme_bw() +
aes(long,lat,group=group) +
geom_polygon(aes(fill=fillvar, alpha=groupvar)) + # shading also for groupvar
geom_path(color="black") +
coord_equal() +
scale_fill_viridis("Fill", na.value="black") +
geom_point(inherit.aes=FALSE, data=pointsdf, aes(x=x, y=y, group=groupvar, col=groupvar), size=1) +
scale_color_manual('Alpha + colour', values=c("black","transparent","white")) +
scale_alpha_manual('Alpha + colour', values=c(0.8,0.8, 1)) +
theme(legend.key = element_rect(colour = "black"), legend.box = "vertical", legend.position = "top") +
guides(alpha=guide_legend(override.aes = list(alpha=c(1,1,1), fill=c('white','white','black'))))
grid.arrange(sizeover, nosizeover, ncol=2)
两个图(sizeover
和nosizeover
)都存在这个问题,只是前者更明显。有罪的一方是ggplot2中的函数draw_key_polygon()
。它根据 size
设置(请参阅 here)在其绘制的矩形周围创建一些 space。我不太清楚为什么要这样写,但大概是有原因的。
最简单的解决方案类似于 将图例绘制功能替换为geom_polygon()
。在这种情况下,我们甚至不必自己编写新的,我们可以使用现有的:
GeomPolygon$draw_key <- ggplot2::draw_key_rect
sizeover
这造成的唯一问题是现在图例轮廓看起来有点细,因为填充的矩形绘制在轮廓之上。我们可以通过将线加粗一点来解决这个问题,方法是将其添加到绘图中:
+ theme(legend.key = element_rect(colour = "black", size = 1))
这对我来说似乎是一个合理的解决方案。
请注意,geom_polygon()
将在剩余的会话中继续使用修改后的图例绘制功能。要撤消,运行:
GeomPolygon$draw_key <- ggplot2::draw_key_polygon
我最近对与
因此,我创建了一个类似的 hack,但在一个相当复杂的情节中,我试图同时展示几件事。该图需要将点的大小设置为较小的值,因此我需要 override.aes
在图例中有足够大的点。因为我使用了 alpha
和 colour
,所以我将两者都引入了同一个图例键。
然而,奇怪的是(至少对我而言),aes
覆盖在图例键框边距和填充之间创建了难看的空白,如带有和不带有大小 aes 覆盖的地图所示:
这是怎么发生的,我怎样才能让它消失?任何帮助将不胜感激。
这是重现此代码的代码。如前所述,我的真实情节比这更复杂,但这显示了总体思路。
## create an example using the world data
require(rworldmap)
require(rgeos)
require(ggplot2)
require(viridis)
## Load world map and subset
world <- getMap()
world <- world[!world@data$ADMIN %in% c("French Southern and Antarctic Lands",
"Heard Island and McDonald Islands",
"French Guiana"),] #NA entries for these in REGION col
world <- world[world@data$REGION == "South America",]
world@data$id = rownames(world@data)
## create example where we have NA for the fill variable
world@data$fillvar <- world@data$LAT
world@data$fillvar[round(world@data$LAT) == -9] <- NA #Peru
## create spatial data frame for plotting
polydf = ggplot2::fortify(world, region="id")
polydf <- merge(polydf, world@data, by="id")
## create arbitrary grouping variable
polydf$groupvar <- ifelse(polydf$NAME == "Bolivia", "Bolivia", "NotBolivia") # the two main classes
# simulate hack where we name the NA fill case as a new grouping level (which we will use alpha for)
polydf$groupvar[is.na(polydf$fillvar)] <- 'Removed'
polydf$groupvar <- factor(polydf$groupvar)
## create centroid points to show the grouping with points, again manual hack for NA
pointsdf <- gCentroid(world[!is.na(world@data$fillvar),],byid=TRUE)
pointsdf <- as.data.frame(pointsdf@coords)
pointsdf$groupvar <- ifelse(rownames(pointsdf)=="Bolivia","Bolivia","NotBolivia")
pointsNA <- gCentroid(world[is.na(world@data$fillvar),], byid=TRUE)
pointsNA <- as.data.frame(pointsNA@coords)
pointsNA$groupvar <- "Removed"
pointsdf <- rbind(pointsdf, pointsNA)
pointsdf$groupvar <- factor(pointsdf$groupvar)
## plot with override.aes for size
sizeover <- ggplot(polydf) + theme_bw() +
aes(long,lat,group=group) +
geom_polygon(aes(fill=fillvar, alpha=groupvar)) + # shading also for groupvar
geom_path(color="black") +
coord_equal() +
scale_fill_viridis("Fill", na.value="black") +
geom_point(inherit.aes=FALSE, data=pointsdf, aes(x=x, y=y, group=groupvar, col=groupvar), size=1) +
scale_color_manual('Alpha + colour', values=c("black","transparent","white")) +
scale_alpha_manual('Alpha + colour', values=c(0.8,0.8, 1)) +
theme(legend.key = element_rect(colour = "black"), legend.box = "vertical", legend.position = "top") +
guides(color=guide_legend(override.aes = list(size=2)),
alpha=guide_legend(override.aes = list(alpha=c(1,1,1), fill=c('white','white','black'))))
## plot without override.aes for size
nosizeover <- ggplot(polydf) + theme_bw() +
aes(long,lat,group=group) +
geom_polygon(aes(fill=fillvar, alpha=groupvar)) + # shading also for groupvar
geom_path(color="black") +
coord_equal() +
scale_fill_viridis("Fill", na.value="black") +
geom_point(inherit.aes=FALSE, data=pointsdf, aes(x=x, y=y, group=groupvar, col=groupvar), size=1) +
scale_color_manual('Alpha + colour', values=c("black","transparent","white")) +
scale_alpha_manual('Alpha + colour', values=c(0.8,0.8, 1)) +
theme(legend.key = element_rect(colour = "black"), legend.box = "vertical", legend.position = "top") +
guides(alpha=guide_legend(override.aes = list(alpha=c(1,1,1), fill=c('white','white','black'))))
grid.arrange(sizeover, nosizeover, ncol=2)
两个图(sizeover
和nosizeover
)都存在这个问题,只是前者更明显。有罪的一方是ggplot2中的函数draw_key_polygon()
。它根据 size
设置(请参阅 here)在其绘制的矩形周围创建一些 space。我不太清楚为什么要这样写,但大概是有原因的。
最简单的解决方案类似于geom_polygon()
。在这种情况下,我们甚至不必自己编写新的,我们可以使用现有的:
GeomPolygon$draw_key <- ggplot2::draw_key_rect
sizeover
这造成的唯一问题是现在图例轮廓看起来有点细,因为填充的矩形绘制在轮廓之上。我们可以通过将线加粗一点来解决这个问题,方法是将其添加到绘图中:
+ theme(legend.key = element_rect(colour = "black", size = 1))
这对我来说似乎是一个合理的解决方案。
请注意,geom_polygon()
将在剩余的会话中继续使用修改后的图例绘制功能。要撤消,运行:
GeomPolygon$draw_key <- ggplot2::draw_key_polygon