r - ggplot 停止 geom_segment 显示在图例中的 geom_boxplot
问题描述
我试图得到类似于 Glen_b 对这个问题的回答。基本上,我希望在箱线图顶部有一个箭头,表示使用 ggplot 有更多超出比例的异常值。
我可以让情节的主要部分看起来像我想要的那样,但我在获得一个明智的传说时遇到了问题。
我整理了一个例子:
library(plyr)
library(dplyr)
library(ggplot2)
#create test data frame with extreme outlier
mpg_test <- mpg
mpg_test[1,"hwy"] = 250
pmax = 50
pmin = min(mpg_test$hwy)
outliersabovepmax <- filter(mpg_test, hwy > pmax) %>% mutate(hwy= pmax)
#basic plot without cropping/adding arrows
p <- ggplot(mpg_test, aes(x = class, y=hwy, colour = class)) + geom_boxplot()
p
我可以让情节的主体看起来像我想要的那样:
#plot that I want
p2 <- p +
geom_segment(data = outliersabovepmax,
aes(xend = class, y = hwy-1, yend = hwy+1,
linetype = "Outlier above"),
arrow = arrow(), show.legend = T) +
coord_cartesian(ylim = c(pmin, pmax))
但我希望图例不显示颜色图例上的箭头。
我通常希望能够按照以下方式做一些事情:
p2 +
guides(colour = guide_legend(override.aes = list(linetype = "blank")))
但是因为箱线图也使用线型,所以如果我这样做,我只会得到黑色方块。我也不想设置show.legend = F
,geom_segment
因为我想在图例中有箭头。
作为奖励,我希望将图例中的箭头旋转为面朝上。但这并不重要。
我得到的情节:
解决方案
也许是这样的?
p +
# hide legend in actual segment layer
geom_segment(data = outliersabovepmax,
aes(xend = class, y = hwy-1, yend = hwy+1),
arrow = arrow(), show.legend = F)+
# have invisible segment layer that shows legend
geom_segment(data = outliersabovepmax,
aes(xend = class, y = hwy-1, yend = hwy+1, linetype = "Outlier above"),
arrow = arrow(), alpha = 0, show.legend = T) +
# override alpha for linetype legend
guides(linetype = guide_legend(override.aes = list(alpha = 1))) +
coord_cartesian(ylim = c(pmin, pmax))
如果您想更改 的geom_segment
图例键的布局,您可以深入研究以下代码GeomSegment
:
library(grid)
GeomSegment2 <- ggproto("GeomSegment2", GeomSegment,
draw_key = function (data, params, size) {
data$linetype[is.na(data$linetype)] <- 0
segmentsGrob(
# vertical instead of horizontal line
0.5, 0.1, 0.5, 0.9, #0.1, 0.5, 0.9, 0.5,
gp = gpar(col = alpha(data$colour, data$alpha),
lwd = data$size * .pt,
lty = data$linetype,
lineend = "butt"),
arrow = params$arrow)
})
geom_segment2 <- function (mapping = NULL, data = NULL, stat = "identity",
position = "identity", ..., arrow = NULL, arrow.fill = NULL,
lineend = "butt", linejoin = "round", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE) {
layer(data = data, mapping = mapping, stat = stat, geom = GeomSegment2,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(arrow = arrow, arrow.fill = arrow.fill,
lineend = lineend, linejoin = linejoin, na.rm = na.rm,
...))
}
用法:
p +
# hide legend in actual segment layer
geom_segment(data = outliersabovepmax,
aes(xend = class, y = hwy-1, yend = hwy+1),
arrow = arrow(), show.legend = F)+
# have invisible segment layer that shows legend
geom_segment2(data = outliersabovepmax,
aes(xend = class, y = hwy-1, yend = hwy+1, linetype = "Outlier above"),
arrow = arrow(), alpha = 0, show.legend = T) +
# override alpha for linetype legend
guides(linetype = guide_legend(override.aes = list(alpha = 1))) +
coord_cartesian(ylim = c(pmin, pmax))
推荐阅读
- javascript - NodeJS 变量提升
- java - 如何将旧版 j2ee 应用程序从 JDK 1.3.1 迁移/运行到 JDK1.6
- sql-server - 无法在 SQL Server 管理控制台中访问 Visual Studio 数据库
- multithreading - Qt 应用程序使用使用多线程的库时的多线程问题
- c# - C#中的SELECT查询
- javascript - 如何在元素之后查找文本和/或标签?(jQuery,JS)
- android - 如何在不使用任何自定义视图或库的情况下使 bottomNavigationView 徽章覆盖项目图标?
- mysql - 我应该使用什么 IP 地址通过 AWS Site-to-Site VPN 从 Lambda 函数查询 MySQL 数据库?
- c++ - 得到 CC1plus.exe 致命错误:c:\mydirectory\include 没有这样的文件或目录
- python - 如何计算随机生成的值之间的马氏距离?