使用 ggplot2 + gridExtra 进行无边界合并和调整绘图大小

Borderless merge and adjusted plot size with ggplot2 + gridExtra

我想将 3 个地块无缝地合并在一起。我的问题是这些图略有偏移,即使我没有边框地绘制它们,它们也不会在图 1 和图 2 / 图 2 和图 3 之间无缝合并。

library(tidyverse)
library(gridExtra)

plot1 <- ggplot(df) +
  theme_dark() +
  geom_line(aes(y = Price, x = time, color = "#00FFFF"), size = 0.7) +
  geom_area(aes(y = Price, x = time), fill = "#00FFFF", alpha = .1) +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        legend.position = c(.1, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(3, 3, 3, 3),
        plot.margin = margin(0,-0.5,-0.5,-0.5),
        plot.background = element_rect(fill = "#808080")) +
  scale_colour_manual(name = "Price", 
                      values = c("#00FFFF" = "#00FFFF"), labels = c("Stock")) +
  labs(y = "")
#  
plot1
#
plot2 <- ggplot(df) +
  theme_dark() +
  geom_bar(aes(x = time, y = B, fill = "green"), stat = "identity") +
  geom_bar(aes(x = time, y = S, fill = "red"), stat = "identity") +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        panel.border = element_blank(),
        legend.position = c(.1, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(3, 3, 3, 3),
        plot.margin = margin(-0.75,-0.5,0,-0.5),
        plot.background = element_rect(fill = "#808080")) +
  scale_fill_identity(name = "Volume",
                      guide = "legend", labels = c("B", "S")) +
  labs(y = "")
#
plot2
#
plot3 <- ggplot(df) +
  theme_dark() +
  geom_line(aes(y = EMA_short, x = time, color = "blue"), size = 0.7) +
  geom_area(aes(y = EMA_short, x = time), fill = "blue", alpha = .1) +
  geom_line(aes(y = EMA_long, x = time, color = "yellow"), size = 0.7) +
  geom_area(aes(y = EMA_long, x = time), fill = "yellow", alpha = .1) +
  theme(axis.title.x=element_blank(),
        axis.ticks.x=element_blank(),
        panel.border = element_blank(),
        legend.position = c(.1, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(3, 3, 3, 3),
        plot.margin = margin(-0.75,-0.5,2,-0.5),
        plot.background = element_rect(fill = "#808080")) +
  scale_colour_manual(name = "EMA", 
                      values = c("blue" = "blue", "yellow" = "yellow"), labels = c("EMA50", "EMA200")) +
  labs(y = "")
#
plot3
#
gA <- ggplotGrob(plot1)
gB <- ggplotGrob(plot2)
gC <- ggplotGrob(plot3)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB, gC))

在我看来,我希望这 3 个地块以与此处类似的方式相互合并:

非常感谢任何建议。

编辑

感谢您提供非常有帮助的答案。我现在只有两个小的光学问题。尽管我将所有图例都放置在相同位置,但它们位于其他位置。我应该将它们全部格式化为相同的大小吗?不幸的是,左侧有两个小白点,如图所示。我已经尝试使边缘变大或变小,但那里的斑点总是白色的。我在上面更新了我的新代码。谢谢!

你应该考虑 expand(c(0,0)) and/or theme(plot.margin = c(t,r,b,l))

首先,为每个绘图添加 x 和 y 扩展参数,以抑制数据周围的空白 space,这是 ggplot 的默认值:

plot1 + scale_y_continuous("", expand = c(0,0)) 
# we indicate here 'no label', so you should supress '+ ylab()'
plot1 + scale_x_datetime("", expand = c(0,0)) 
# same, you should supress 'xlab()' from the plots
  1. 这让您可以通过 grid.arrange 在绘图之间添加最小边距,并且您可以使用 theme(plot.margin = c(t,r,b,l)) 调整这些边距(例如,plot1 +theme(plot.margin(-0.5,-0.5,-0.5,-0.5)))。在你的情况下,你可能需要处理 2 个图的顶部 and/or 底部(如果其他 2 个没有边距,请注意中间的图)。
  2. 有时您必须调整输出大小(grid.arrange 的高度和宽度),通常是在您保存 arrangegrob 对象时(例如,ggsave( arrangeGrob(plot1, plot2)) 需要处理大小)。
  3. 请注意,您必须将图例放在图表的顶部、底部或内部,以便堆叠具有相同 'data-area' 大小的图表。当图例大小不同时,您不能在左侧或右侧堆叠带有图例的图。因此,为您的 3 个地块添加 +theme(legend.position = 'top'),或添加 bottom 或某个坐标。

1- 您通过 theme() 参数中的指示参数制作了自定义图例,例如,

plot1 + theme(legend.background = element_blank(), legend.text.align=0, legend.title.align = 0))
#a legend with no white background, left text and title alignment. 

2- legend-lines 的区域有 guides() 参数,以指示您的非常特殊的密钥:

# (e.g., remove the little grey area background for the legend):
 plot1 + guides(color=guide_legend(override.aes=list(fill=NA)))

3- 如有必要,请阅读 theme()guides() 函数的一些参数,以便理解 - 倍数 - 主题参数并创建您的 personnal-darky-style-func().