画图给点分组?
小伙伴提出了上面的问题,点不能够打到violin里面去,即使加了aes(group=color)
强行分组也不行。这个照理第一感觉都会觉得可以,但试一下都会发现不行。
library(ggplot2)
d = subset(diamonds, color %in% c("D", "E"))
ggplot(d, aes(cut, carat, fill=color, color=color)) +
geom_violin(alpha=.3) + geom_jitter(width=.05, alpha=.5)
然后我就看到大家各种猜,所谓talk is cheap show me the code,我看一下代码:
GeomPoint <- ggproto("GeomPoint", Geom,
required_aes = c("x", "y"),
non_missing_aes = c("size", "shape", "colour"),
default_aes = aes(
shape = 19, colour = "black", size = 1.5, fill = NA,
alpha = NA, stroke = 0.5
),
draw_panel = function(data, panel_params, coord, na.rm = FALSE) {
coords <- coord$transform(data, panel_params)
ggname("geom_point",
pointsGrob(
coords$x, coords$y,
pch = coords$shape,
gp = gpar(
col = alpha(coords$colour, coords$alpha),
fill = alpha(coords$fill, coords$alpha),
# Stroke is added around the outside of the point
fontsize = coords$size * .pt + coords$stroke * .stroke / 2,
lwd = coords$stroke * .stroke / 2
)
)
)
},
draw_key = draw_key_point
)
这显而易见,必须是不行了。因为GeomPoint
并没有计算分组。你可能会觉得这显而易见的需求,怎么会不支持!写软件要考虑的因素很多的。
首先打点你为什么能够分组?必须是离散型的变量,你设想一下,连续型变量你能够分组一些点画左边,一些点画右边吗?那x轴怎么搞?所以必须是离散型变量,像上面需求的例子这种。而如果你实现了上面这种需求,那么你怎么能阻止用户不把它应用于连续型变量,所以这种功能不能实现!不是说它不可能实现,我都可以改GeomPoint
改到它可以有这个功能,但不能这么做!教育用户、避免用户做错误的事情是更为重要的事情。你应该理解为什么hadley不实现了,而我也不能去实现它。
难道就不能分组了吗?显然可以的,请记住分面即分组!你可以通过分面来实现。所以不是不行,而是有一套哲学在里面,以一种不会出错的机制来实现。它可能不是所有人想要的,但它是不允许用户出错的方法。
ggplot(d, aes(cut, carat, fill=color, color=color)) +
geom_violin(alpha=.3) + geom_jitter(width=.05, alpha=.5) +
facet_grid(.~color)
可能用户还是不爽,因为用户可能想把同样的cut放在一起来比较,像最初的图一样。又所谓活人不能让尿憋死,难道你不能变通一下吗?我们可以把x轴的变量换掉,同时考虑原先x轴的变量和分组变量。强行自己分组。
d$cut_color <- paste(d$cut, d$color, sep="_")
ggplot(d, aes(cut_color, carat, fill=color, color=color)) +
geom_violin(alpha=.3) + geom_jitter(width=.05, alpha=.5)
活人不能让尿憋死
要说到变通,你还能够乾坤大挪移,我就想按照原来的代码来画,又想把点挪到violin
上,那就挪点呗,只要你懂得变通!凡事皆有可能:
d$xpos = as.numeric(factor(d$cut)) + c(-.22, .22)[as.numeric(factor(d$color))]
ggplot(d, aes(cut, carat, fill=color, color=color)) +
geom_violin(alpha=.3) +
geom_jitter(aes(x=xpos), width=.05, alpha=.5)