我的目标是一个复合图,它结合了散点图和2个图来进行密度估算。我面临的问题是由于密度图的缺失轴标记和散点图的图例,密度图未能与散点图正确对齐。可以通过使用plot.margin
播放arround来调整它。但是,这不是一个更好的解决方案,因为如果对图形进行更改,我将不得不一遍又一遍地进行调整。有没有办法以某种方式定位所有绘图,以便实际绘图面板完美对齐?
我尽量保持代码尽可能小,但为了重现问题,它仍然是非常多的。
library(ggplot2)
library(gridExtra)
df <- data.frame(y = c(rnorm(50, 1, 1), rnorm(50, -1, 1)),
x = c(rnorm(50, 1, 1), rnorm(50, -1, 1)),
group = factor(c(rep(0, 50), rep(1,50))))
empty <- ggplot() +
geom_point(aes(1,1), colour="white") +
theme(
plot.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank()
)
scatter <- ggplot(df, aes(x = x, y = y, color = group)) +
geom_point() +
theme(legend.position = "bottom")
top_plot <- ggplot(df, aes(x = y)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
theme(legend.position = "none") +
theme(axis.title.y = element_blank(),
axis.title.x = element_blank(),
axis.text.y=element_blank(),
axis.text.x=element_blank(),
axis.ticks=element_blank() )
right_plot <- ggplot(df, aes(x = x)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
coord_flip() + theme(legend.position = "none") +
theme(axis.title.y = element_blank(),
axis.title.x = element_blank(),
axis.text.y = element_blank(),
axis.text.x=element_blank(),
axis.ticks=element_blank())
grid.arrange(top_plot, empty, scatter, right_plot, ncol=2, nrow=2, widths=c(4, 1), heights=c(1, 4))
答案 0 :(得分:5)
另一种选择,
library(egg)
ggarrange(top_plot, empty, scatter, right_plot,
ncol=2, nrow=2, widths=c(4, 1), heights=c(1, 4))
答案 1 :(得分:2)
以下是基础R中的解决方案。它使用this question中的line2user
函数。
par(mar = c(5, 4, 6, 6))
with(df, plot(y ~ x, bty = "n", type = "n"))
with(df[df$group == 0, ], points(y ~ x, col = "dodgerblue2"))
with(df[df$group == 1, ], points(y ~ x, col = "darkorange"))
x0_den <- with(df[df$group == 0, ],
density(x, from = par()$usr[1], to = par()$usr[2]))
x1_den <- with(df[df$group == 1, ],
density(x, from = par()$usr[1], to = par()$usr[2]))
y0_den <- with(df[df$group == 0, ],
density(y, from = par()$usr[3], to = par()$usr[4]))
y1_den <- with(df[df$group == 1, ],
density(y, from = par()$usr[3], to = par()$usr[4]))
x_scale <- max(c(x0_den$y, x1_den$y))
y_scale <- max(c(y0_den$y, y1_den$y))
lines(x = x0_den$x, y = x0_den$y/x_scale*2 + line2user(1, 3),
col = "dodgerblue2", xpd = TRUE)
lines(x = x1_den$x, y = x1_den$y/x_scale*2 + line2user(1, 3),
col = "darkorange", xpd = TRUE)
lines(y = y0_den$x, x = y0_den$y/x_scale*2 + line2user(1, 4),
col = "dodgerblue2", xpd = TRUE)
lines(y = y1_den$x, x = y1_den$y/x_scale*2 + line2user(1, 4),
col = "darkorange", xpd = TRUE)
答案 2 :(得分:2)
这是一个使用pBase->foo()
包中plot_grid
和cowplot
包中grid.arrange
组合的选项:
gridExtra
首先,一些设置:将绘图图例提取为单独的grob的函数,以及一些可重用的绘图组件:
library(ggplot2)
library(gridExtra)
library(grid)
library(cowplot)
df <- data.frame(y = c(rnorm(50, 1, 1), rnorm(50, -1, 1)),
x = c(rnorm(50, 1, 1), rnorm(50, -1, 1)),
group = factor(c(rep(0, 50), rep(1,50))))
创建图:
# Function to extract legend
# https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot) {
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)
}
# Set up reusable plot components
my_thm = list(theme_bw(),
theme(legend.position = "none",
axis.title.y = element_blank(),
axis.title.x = element_blank(),
axis.text.y=element_blank(),
axis.text.x=element_blank(),
axis.ticks=element_blank()))
marg = theme(plot.margin=unit(rep(0,4),"lines"))
现在列出三个情节加上传奇:
## Empty plot
empty <- ggplot() + geom_blank() + marg
## Scatterplot
scatter <- ggplot(df, aes(x = x, y = y, color = group)) +
geom_point() +
theme_bw() + marg +
guides(colour=guide_legend(ncol=2))
# Copy legend from scatterplot as a separate grob
leg = g_legend(scatter)
# Remove legend from scatterplot
scatter = scatter + theme(legend.position = "none")
## Top density plot
top_plot <- ggplot(df, aes(x = y)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
my_thm + marg
## Right density plot
right_plot <- ggplot(df, aes(x = x)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
coord_flip() + my_thm + marg
答案 3 :(得分:1)
使用Align ggplot2 plots vertically的答案通过添加到gtable来对齐情节(最有可能使这一点复杂化)
library(ggplot2)
library(gtable)
library(grid)
您的数据和图表
set.seed(1)
df <- data.frame(y = c(rnorm(50, 1, 1), rnorm(50, -1, 1)),
x = c(rnorm(50, 1, 1), rnorm(50, -1, 1)),
group = factor(c(rep(0, 50), rep(1,50))))
scatter <- ggplot(df, aes(x = x, y = y, color = group)) +
geom_point() + theme(legend.position = "bottom")
top_plot <- ggplot(df, aes(x = y)) +
geom_density(alpha=.5, mapping = aes(fill = group))+
theme(legend.position = "none")
right_plot <- ggplot(df, aes(x = x)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
coord_flip() + theme(legend.position = "none")
使用Bapistes回答的想法
g <- ggplotGrob(scatter)
g <- gtable_add_cols(g, unit(0.2,"npc"))
g <- gtable_add_grob(g, ggplotGrob(right_plot)$grobs[[4]], t = 2, l=ncol(g), b=3, r=ncol(g))
g <- gtable_add_rows(g, unit(0.2,"npc"), 0)
g <- gtable_add_grob(g, ggplotGrob(top_plot)$grobs[[4]], t = 1, l=4, b=1, r=4)
grid.newpage()
grid.draw(g)
哪个产生
我使用ggplotGrob(right_plot)$grobs[[4]]
手动选择panel
grob,但当然可以自动执行此操作
答案 4 :(得分:0)
当您将轴设置为element_blank()
时,它会移除轴并允许图形填充剩余的空间。相反,设置为color =&#34; white&#34; (或者你的背景是什么):
# All other code remains the same:
scatter <- ggplot(df, aes(x = x, y = y, color = group)) +
geom_point() +
theme(legend.position = "bottom")
top_plot <- ggplot(df, aes(x = y)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
theme(legend.position = "none")+
theme(axis.title = element_text(color = "white"),
axis.text=element_text(color = "white"),
axis.ticks=element_line(color = "white") )
right_plot <- ggplot(df, aes(x = x)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
coord_flip() +
theme(legend.position = "bottom") +
theme(axis.title = element_text(color = "white"),
axis.text = element_text(color = "white"),
axis.ticks=element_line(color = "white"))
grid.arrange(top_plot, empty, scatter, right_plot, ncol=2, nrow=2, widths=c(4, 1), heights=c(1, 4))
我还必须在正确的情节中添加一个图例。如果您不想这样做,我还建议您将散点中的图例移动到图中:
scatter <- ggplot(df, aes(x = x, y = y, color = group)) +
geom_point() +
theme(legend.position = c(0.05,0.1))
top_plot <- ggplot(df, aes(x = y)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
theme(legend.position = "none")+
theme(axis.title = element_text(color = "white"),
axis.text=element_text(color = "white"),
axis.ticks=element_line(color = "white") )
right_plot <- ggplot(df, aes(x = x)) +
geom_density(alpha=.5, mapping = aes(fill = group)) +
coord_flip() +
theme(legend.position = "none") +
theme(axis.title = element_text(color = "white"),
axis.text = element_text(color = "white"),
axis.ticks=element_line(color = "white"))
grid.arrange(top_plot, empty, scatter, right_plot, ncol=2, nrow=2, widths=c(4, 1), heights=c(1, 4))