使用 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
- 这让您可以通过 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 个没有边距,请注意中间的图)。
- 有时您必须调整输出大小(grid.arrange 的高度和宽度),通常是在您保存 arrangegrob 对象时(例如,
ggsave( arrangeGrob(plot1, plot2))
需要处理大小)。
- 请注意,您必须将图例放在图表的顶部、底部或内部,以便堆叠具有相同 '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()
.
我想将 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
- 这让您可以通过 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 个没有边距,请注意中间的图)。 - 有时您必须调整输出大小(grid.arrange 的高度和宽度),通常是在您保存 arrangegrob 对象时(例如,
ggsave( arrangeGrob(plot1, plot2))
需要处理大小)。 - 请注意,您必须将图例放在图表的顶部、底部或内部,以便堆叠具有相同 '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()
.