用 geom_violin 填充透明度
Fill transparency with geom_violin
如何增加小提琴图填充的 alpha 而不是边界线的 alpha?
将 alpha 作为参数更改为 geom_violin()
会导致填充和线条发生变化。
如果您希望避免绘制两次,可以执行以下操作。自从引入 extension mechanism we can easily modify the existing source code 来定义我们自己的 geoms。
首先我们需要检查 geom_violin
. The actual plotting is done with GeomPolygon$draw_panel(newdata, ...)
. So the trick is to tinker with geom_polygon
中发生了什么。所需的修改非常简单:在绘图块中
polygonGrob(munched$x, munched$y, default.units = "native",
id = munched$group,
gp = gpar(
col = alpha(first_rows$colour, first_rows$alpha),
fill = alpha(first_rows$fill, first_rows$alpha),
lwd = first_rows$size * .pt,
lty = first_rows$linetype
)
)
只需将颜色规格替换为 col = first_rows$colour
。
好的,我们可以开始了。只需声明我们的自定义 geom_violin2
,从原始来源借用代码并应用几个 ad-hoc 修复。
library(grid)
GeomPolygon2 <- ggproto("GeomPolygon2", Geom,
draw_panel = function(data, panel_scales, coord) {
n <- nrow(data)
if (n == 1) return(zeroGrob())
munched <- coord_munch(coord, data, panel_scales)
munched <- munched[order(munched$group), ]
first_idx <- !duplicated(munched$group)
first_rows <- munched[first_idx, ]
ggplot2:::ggname("geom_polygon",
polygonGrob(munched$x, munched$y, default.units = "native",
id = munched$group,
gp = gpar(
col = first_rows$colour,
fill = alpha(first_rows$fill, first_rows$alpha),
lwd = first_rows$size * .pt,
lty = first_rows$linetype
)
)
)
},
default_aes = aes(colour = "NA", fill = "grey20", size = 0.5, linetype = 1,
alpha = NA),
handle_na = function(data, params) {
data
},
required_aes = c("x", "y"),
draw_key = draw_key_polygon
)
`%||%` <- function (a, b)
{
if (!is.null(a))
a
else b
}
GeomViolin2 <- ggproto("GeomViolin", Geom,
setup_data = function(data, params) {
data$width <- data$width %||%
params$width %||% (resolution(data$x, FALSE) * 0.9)
plyr::ddply(data, "group", transform,
xmin = x - width / 2,
xmax = x + width / 2
)
},
draw_group = function(self, data, ..., draw_quantiles = NULL) {
data <- transform(data,
xminv = x - violinwidth * (x - xmin),
xmaxv = x + violinwidth * (xmax - x)
)
newdata <- rbind(
plyr::arrange(transform(data, x = xminv), y),
plyr::arrange(transform(data, x = xmaxv), -y)
)
newdata <- rbind(newdata, newdata[1,])
if (length(draw_quantiles) > 0) {
stopifnot(all(draw_quantiles >= 0), all(draw_quantiles <= 1))
quantiles <- create_quantile_segment_frame(data, draw_quantiles)
aesthetics <- data[
rep(1, nrow(quantiles)),
setdiff(names(data), c("x", "y")),
drop = FALSE
]
both <- cbind(quantiles, aesthetics)
quantile_grob <- GeomPath$draw_panel(both, ...)
ggplot2:::ggname("geom_violin", grobTree(
GeomPolygon2$draw_panel(newdata, ...),
quantile_grob)
)
} else {
ggplot2:::ggname("geom_violin", GeomPolygon2$draw_panel(newdata, ...))
}
},
draw_key = draw_key_polygon,
default_aes = aes(weight = 1, colour = "grey20", fill = "white", size = 0.5,
alpha = NA, linetype = "solid"),
required_aes = c("x", "y")
)
geom_violin2 <- function(mapping = NULL, data = NULL, stat = "ydensity",
draw_quantiles = NULL, position = "dodge",
trim = TRUE, scale = "area",
na.rm = FALSE, show.legend = NA, inherit.aes = TRUE,
...) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomViolin2,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
trim = trim,
scale = scale,
draw_quantiles = draw_quantiles,
na.rm = na.rm,
...
)
)
}
现在看!颜色有问题,我承认。但是可以清楚的看到边框没有受到alpha
.
的影响
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_violin2(alpha = 0.7, size = 3, colour = "blue", fill = "red")
如何增加小提琴图填充的 alpha 而不是边界线的 alpha?
将 alpha 作为参数更改为 geom_violin()
会导致填充和线条发生变化。
如果您希望避免绘制两次,可以执行以下操作。自从引入 extension mechanism we can easily modify the existing source code 来定义我们自己的 geoms。
首先我们需要检查 geom_violin
. The actual plotting is done with GeomPolygon$draw_panel(newdata, ...)
. So the trick is to tinker with geom_polygon
中发生了什么。所需的修改非常简单:在绘图块中
polygonGrob(munched$x, munched$y, default.units = "native",
id = munched$group,
gp = gpar(
col = alpha(first_rows$colour, first_rows$alpha),
fill = alpha(first_rows$fill, first_rows$alpha),
lwd = first_rows$size * .pt,
lty = first_rows$linetype
)
)
只需将颜色规格替换为 col = first_rows$colour
。
好的,我们可以开始了。只需声明我们的自定义 geom_violin2
,从原始来源借用代码并应用几个 ad-hoc 修复。
library(grid)
GeomPolygon2 <- ggproto("GeomPolygon2", Geom,
draw_panel = function(data, panel_scales, coord) {
n <- nrow(data)
if (n == 1) return(zeroGrob())
munched <- coord_munch(coord, data, panel_scales)
munched <- munched[order(munched$group), ]
first_idx <- !duplicated(munched$group)
first_rows <- munched[first_idx, ]
ggplot2:::ggname("geom_polygon",
polygonGrob(munched$x, munched$y, default.units = "native",
id = munched$group,
gp = gpar(
col = first_rows$colour,
fill = alpha(first_rows$fill, first_rows$alpha),
lwd = first_rows$size * .pt,
lty = first_rows$linetype
)
)
)
},
default_aes = aes(colour = "NA", fill = "grey20", size = 0.5, linetype = 1,
alpha = NA),
handle_na = function(data, params) {
data
},
required_aes = c("x", "y"),
draw_key = draw_key_polygon
)
`%||%` <- function (a, b)
{
if (!is.null(a))
a
else b
}
GeomViolin2 <- ggproto("GeomViolin", Geom,
setup_data = function(data, params) {
data$width <- data$width %||%
params$width %||% (resolution(data$x, FALSE) * 0.9)
plyr::ddply(data, "group", transform,
xmin = x - width / 2,
xmax = x + width / 2
)
},
draw_group = function(self, data, ..., draw_quantiles = NULL) {
data <- transform(data,
xminv = x - violinwidth * (x - xmin),
xmaxv = x + violinwidth * (xmax - x)
)
newdata <- rbind(
plyr::arrange(transform(data, x = xminv), y),
plyr::arrange(transform(data, x = xmaxv), -y)
)
newdata <- rbind(newdata, newdata[1,])
if (length(draw_quantiles) > 0) {
stopifnot(all(draw_quantiles >= 0), all(draw_quantiles <= 1))
quantiles <- create_quantile_segment_frame(data, draw_quantiles)
aesthetics <- data[
rep(1, nrow(quantiles)),
setdiff(names(data), c("x", "y")),
drop = FALSE
]
both <- cbind(quantiles, aesthetics)
quantile_grob <- GeomPath$draw_panel(both, ...)
ggplot2:::ggname("geom_violin", grobTree(
GeomPolygon2$draw_panel(newdata, ...),
quantile_grob)
)
} else {
ggplot2:::ggname("geom_violin", GeomPolygon2$draw_panel(newdata, ...))
}
},
draw_key = draw_key_polygon,
default_aes = aes(weight = 1, colour = "grey20", fill = "white", size = 0.5,
alpha = NA, linetype = "solid"),
required_aes = c("x", "y")
)
geom_violin2 <- function(mapping = NULL, data = NULL, stat = "ydensity",
draw_quantiles = NULL, position = "dodge",
trim = TRUE, scale = "area",
na.rm = FALSE, show.legend = NA, inherit.aes = TRUE,
...) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomViolin2,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
trim = trim,
scale = scale,
draw_quantiles = draw_quantiles,
na.rm = na.rm,
...
)
)
}
现在看!颜色有问题,我承认。但是可以清楚的看到边框没有受到alpha
.
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_violin2(alpha = 0.7, size = 3, colour = "blue", fill = "red")