在密度图下方添加箱线图 [英] Adding boxplot below density plot
问题描述
我是ggplot的新手,正在尝试创建此图:
I'm new to ggplot and I'm trying to create this graph:
但是实际上,我只是停留在这里:
But actually, I'm just stuck here:
这是我的代码:
ggplot(diamonds) +
aes(x = carat, group = cut) +
geom_line(stat = "density", size = 1) +
theme_grey() +
facet_wrap(~cut, nrow = 5, strip.position = "right") +
geom_boxplot(aes())
有人知道我下一步可以做什么吗?
Does someone know what I can do next?
推荐答案
自ggplot2 3.3.0起,可以在ggplot2中完成此操作,而无需任何扩展包.
在包裹的新闻下,功能:
所有具有方向(即x和y轴在哪里)的几何和统计 有不同的解释),现在可以自由选择方向了, 而不是依赖
coord_flip()
.方向从 美观的贴图,但也可以直接使用新的贴图指定orientation
参数(@ thomasp85,#3506).
All geoms and stats that had a direction (i.e. where the x and y axes had different interpretation), can now freely choose their direction, instead of relying on
coord_flip()
. The direction is deduced from the aesthetic mapping, but can also be specified directly with the neworientation
argument (@thomasp85, #3506).
以下内容现在将直接起作用(将原始答案中所有对geom_boxploth
/stat_boxploth
的引用替换为geom_boxplot
/stat_boxplot
:
The following will now work directly (replacing all references to geom_boxploth
/ stat_boxploth
in the original answer with geom_boxplot
/ stat_boxplot
:
library(ggplot2)
ggplot(diamonds, aes(x = carat, y = -0.5)) +
# horizontal boxplots & density plots
geom_boxplot(aes(fill = cut)) +
geom_density(aes(x = carat), inherit.aes = FALSE) +
# vertical lines at Q1 / Q2 / Q3
stat_boxplot(geom = "vline", aes(xintercept = ..xlower..)) +
stat_boxplot(geom = "vline", aes(xintercept = ..xmiddle..)) +
stat_boxplot(geom = "vline", aes(xintercept = ..xupper..)) +
facet_grid(cut ~ .) +
scale_fill_discrete()
原始答案
可以使用水平箱线图geom_boxploth()
/stat_boxploth()
轻松完成此操作,该图可在 ggstance 包:
This can be done easily with a horizontal boxplot geom_boxploth()
/ stat_boxploth()
, found in the ggstance package:
library(ggstance)
ggplot(diamonds, aes(x = carat, y = -0.5)) +
# horizontal box plot
geom_boxploth(aes(fill = cut)) +
# normal density plot
geom_density(aes(x = carat), inherit.aes = FALSE) +
# vertical lines at Q1 / Q2 / Q3
stat_boxploth(geom = "vline", aes(xintercept = ..xlower..)) +
stat_boxploth(geom = "vline", aes(xintercept = ..xmiddle..)) +
stat_boxploth(geom = "vline", aes(xintercept = ..xupper..)) +
facet_grid(cut ~ .) +
# reproduce original chart's color scale (o/w ordered factors will result
# in viridis scale by default, using the current version of ggplot2)
scale_fill_discrete()
如果由于某种原因而仅限于ggplot2软件包,则仍然可以这样做,但是由于geom_boxplot()
和geom_density()
朝着不同的方向发展,因此它会变得不那么直接.
If you are limited to the ggplot2 package for one reason or another, it can still be done, but it would be less straightforward, since geom_boxplot()
and geom_density()
go in different directions.
替代1 :计算箱形图的坐标,将结果传递到ggplot()
之前,请先手动翻转它们.以常规方式添加密度层:
Alternative 1: calculate the box plot's coordinates, & flip them manually before passing the results to ggplot()
. Add a density layer in the normal way:
library(dplyr)
library(tidyr)
p.box <- ggplot(diamonds, aes(x = cut, y = carat)) + geom_boxplot()
p.box.data <- layer_data(p.box) %>%
select(x, ymin, lower, middle, upper, ymax, outliers) %>%
mutate(cut = factor(x, labels = levels(diamonds$cut), ordered = TRUE)) %>%
select(-x)
ggplot(p.box.data) +
# manually plot flipped boxplot
geom_segment(aes(x = ymin, xend = ymax, y = -0.5, yend = -0.5)) +
geom_rect(aes(xmin = lower, xmax = upper, ymin = -0.75, ymax = -0.25, fill = cut),
color = "black") +
geom_point(data = . %>% unnest(outliers),
aes(x = outliers, y = -0.5)) +
# vertical lines at Q1 / Q2 / Q3
geom_vline(data = . %>% select(cut, lower, middle, upper) %>% gather(key, value, -cut),
aes(xintercept = value)) +
# density plot
geom_density(data = diamonds, aes(x = carat)) +
facet_grid(cut ~ .) +
labs(x = "carat") +
scale_fill_discrete()
替代2 :计算密度图的坐标&将结果传递到ggplot()
之前,请先手动翻转它们.以常规方式添加箱形图图层.翻转整个图表:
Alternative 2: calculate the density plot's coordinates, & flip them manually before passing the results to ggplot()
. Add a box plot layer in the normal way. Flip the whole chart:
p.density <- ggplot(diamonds, aes(x = carat, group = cut)) + geom_density()
p.density.data <- layer_data(p.density) %>%
select(x, y, group) %>%
mutate(cut = factor(group, labels = levels(diamonds$cut), ordered = TRUE)) %>%
select(-group)
p.density.data <- p.density.data %>%
rbind(p.density.data %>%
group_by(cut) %>%
filter(x == min(x)) %>%
mutate(y = 0) %>%
ungroup())
ggplot(diamonds, aes(x = -0.5, y = carat)) +
# manually flipped density plot
geom_polygon(data = p.density.data, aes(x = y, y = x),
fill = NA, color = "black") +
# box plot
geom_boxplot(aes(fill = cut, group = cut)) +
# vertical lines at Q1 / Q2 / Q3
stat_boxplot(geom = "hline", aes(yintercept = ..lower..)) +
stat_boxplot(geom = "hline", aes(yintercept = ..middle..)) +
stat_boxplot(geom = "hline", aes(yintercept = ..upper..)) +
facet_grid(cut ~ .) +
scale_fill_discrete() +
coord_flip()
这篇关于在密度图下方添加箱线图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!