使用 ggplot2 组合箱线图和直方图
Posted
技术标签:
【中文标题】使用 ggplot2 组合箱线图和直方图【英文标题】:Combination Boxplot and Histogram using ggplot2 【发布时间】:2011-05-31 21:31:16 【问题描述】:我正在尝试结合直方图和箱线图来可视化连续变量。这是我到目前为止的代码
require(ggplot2)
require(gridExtra)
p1 = qplot(x = 1, y = mpg, data = mtcars, xlab = "", geom = 'boxplot') +
coord_flip()
p2 = qplot(x = mpg, data = mtcars, geom = 'histogram')
grid.arrange(p2, p1, widths = c(1, 2))
除了 x 轴对齐之外,它看起来很好。谁能告诉我如何对齐它们?
或者,如果有人有更好的方法使用ggplot2
制作此图表,那也将不胜感激。
【问题讨论】:
您最初的问题是关于如何使用 ggplot 来实现,但是,您标记为“已接受”的答案使用了 qplot。这是另一回事。不过,这可能会达到目的,我们可以看到现在下面有一个 ggplot 答案。 【参考方案1】:您可以通过 ggExtra 中的 coord_cartesian() 和 align.plots 来做到这一点。
library(ggplot2)
library(ggExtra) # from R-forge
p1 <- qplot(x = 1, y = mpg, data = mtcars, xlab = "", geom = 'boxplot') +
coord_flip(ylim=c(10,35), wise=TRUE)
p2 <- qplot(x = mpg, data = mtcars, geom = 'histogram') +
coord_cartesian(xlim=c(10,35), wise=TRUE)
align.plots(p1, p2)
这里是 align.plot 的修改版本,用于指定每个面板的相对大小:
align.plots2 <- function (..., vertical = TRUE, pos = NULL)
dots <- list(...)
if (is.null(pos)) pos <- lapply(seq(dots), I)
dots <- lapply(dots, ggplotGrob)
ytitles <- lapply(dots, function(.g) editGrob(getGrob(.g,
"axis.title.y.text", grep = TRUE), vp = NULL))
ylabels <- lapply(dots, function(.g) editGrob(getGrob(.g,
"axis.text.y.text", grep = TRUE), vp = NULL))
legends <- lapply(dots, function(.g) if (!is.null(.g$children$legends))
editGrob(.g$children$legends, vp = NULL)
else ggplot2:::.zeroGrob)
gl <- grid.layout(nrow = do.call(max,pos))
vp <- viewport(layout = gl)
pushViewport(vp)
widths.left <- mapply(`+`, e1 = lapply(ytitles, grobWidth),
e2 = lapply(ylabels, grobWidth), SIMPLIFY = F)
widths.right <- lapply(legends, function(g) grobWidth(g) +
if (is.zero(g))
unit(0, "lines")
else unit(0.5, "lines"))
widths.left.max <- max(do.call(unit.c, widths.left))
widths.right.max <- max(do.call(unit.c, widths.right))
for (ii in seq_along(dots))
pushViewport(viewport(layout.pos.row = pos[[ii]]))
pushViewport(viewport(x = unit(0, "npc") + widths.left.max -
widths.left[[ii]], width = unit(1, "npc") - widths.left.max +
widths.left[[ii]] - widths.right.max + widths.right[[ii]],
just = "left"))
grid.draw(dots[[ii]])
upViewport(2)
用法:
# 5 rows, with 1 for p1 and 2-5 for p2
align.plots2(p1, p2, pos=list(1,2:5))
# 5 rows, with 1-2 for p1 and 3-5 for p2
align.plots2(p1, p2, pos=list(1:2,3:5))
【讨论】:
谢谢科什克!!我之前确实尝试过 align.plots,但没有 coord_cartesian 选项,它产生的结果与 grid.arrange 相同。有没有办法像 grid.arrange 一样指定两个图的高度?我希望箱线图的高度小于直方图。 再次感谢科斯克。这完美无缺。也许您应该将此补丁发送给 ggExtra 的作者,因为我相信这是一个非常有用的功能!【参考方案2】:使用 ggplot2 的另一种可能的解决方案,但是,到目前为止,我不知道如何缩放这两个图的高度:
require(ggplot2)
require(grid)
fig1 <- ggplot(data = mtcars, aes(x = 1, y = mpg)) +
geom_boxplot( ) +
coord_flip() +
scale_y_continuous(expand = c(0,0), limit = c(10, 35))
fig2 <- ggplot(data = mtcars, aes(x = mpg)) +
geom_histogram(binwidth = 1) +
scale_x_continuous(expand = c(0,0), limit = c(10, 35))
grid.draw(rbind(ggplotGrob(fig1),
ggplotGrob(fig2),
size = "first"))
【讨论】:
【参考方案3】:使用cowplot包。
library(cowplot)
#adding xlim and ylim to align axis.
p1 = qplot(x = 1, y = mpg, data = mtcars, xlab = "", geom = 'boxplot') +
coord_flip() +
ylim(min(mtcars$mpg),max(mtcars$mpg))
p2 = qplot(x = mpg, data = mtcars, geom = 'histogram')+
xlim(min(mtcars$mpg),max(mtcars$mpg))
#result
plot_grid(p1, p2, labels = c("A", "B"), align = "v",ncol = 1)
【讨论】:
【参考方案4】:我知道的最佳解决方案是使用ggpubr
包:
require(ggplot2)
require(ggpubr)
p1 = qplot(x = 1, y = mpg, data = mtcars, xlab = "", geom = 'boxplot') +
coord_flip()
p2 = qplot(x = mpg, data = mtcars, geom = 'histogram')
ggarrange(p2, p1, heights = c(2, 1), align = "hv", ncol = 1, nrow = 2)
【讨论】:
以上是关于使用 ggplot2 组合箱线图和直方图的主要内容,如果未能解决你的问题,请参考以下文章
R语言ggplot2可视化:组合箱图(boxplot)和直方图(histogram)输出组合可视化结果
MATLAB | 全网最全边际图绘制模板(直方图小提琴图箱线图雨云图散点图... ...)
MATLAB | 全网最全边际图绘制模板(直方图小提琴图箱线图雨云图散点图... ...)
R语言ggplot2可视化:可视化人口金字塔图直方图(堆叠直方图连续变量堆叠直方图离散变量堆叠直方图)密度图箱图(添加抖动数据点tufte箱图多分类变量分组箱图)小提琴图