admin管理员组文章数量:1026989
I am trying to merge multiple ggplot2 plots into a single picture, while retaining control over the respective height of each element. The following code works well and it generates a barplot and a curve plot that are perfectly aligned to each other (see here):
library(ggplot2)
library(grid)
library(gridExtra)
# Save plot as PDF (set to NULL initially)
pdf(file = NULL)
# Data frame for the first plot
df_1 <- data.frame(
data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1,
0.5, 0.1, 0.15, 0.5, 0.5, 0.4),
base = 1:54,
value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085,
10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042,
11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536,
7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262,
20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208,
43.54, 26.7859, 22.2176, 11.0588)
)
# First plot with ggplot
plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) +
geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) +
scale_fill_distiller(palette = 'YlGnBu') +
theme(
axis.text.x = element_text(size = 9, angle = 0, vjust = 0.5),
axis.text.y = element_text(size = 9),
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
)+
xlim(0, 55)
# Data frame for the second plot
df_2 <- data.frame(
x1 = c(4, 12, 1, 2),
x2 = c(9, 15, 24, 54),
y1 = c(0, 0, 0, 0),
y2 = c(0, 0, 0, 0),
priority = c('high', 'low', 'mid', 'high')
)
# Second plot with ggplot
plot_2 <- ggplot(df_2) +
geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority),
curvature = 1, linewidth = 0.5, ncp = 1000) +
expand_limits(y = -1) +
coord_fixed(ratio = 22, ylim = c(-1, 0)) +
scale_colour_brewer(palette = 'YlGnBu') +
theme(
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
) +
xlim(0, 55)
# List of ggplot objects
plots <- list(plot_1, plot_2) # Add as many plots as you need
# Apply a small margin to each plot to reduce extra white space
plots_adjusted <- lapply(plots, "+", theme(plot.margin = margin(0, 0, 0, 0)))
# Convert adjusted plots to gtables
grob_plots <- lapply(plots_adjusted, ggplotGrob)
# Calculate the maximum widths across all plots
max_widths <- do.call(unit.pmax, lapply(grob_plots, function(g) g$widths))
# Set each plot's widths to the calculated maximum widths
grob_plots <- lapply(grob_plots, function(g) { g$widths <- max_widths; g })
# Arrange the grobs with specific heights
combined_plot <- arrangeGrob(grobs = grob_plots, heights = unit(c(1,1), "null"), padding = unit(0, "pt"))
dev.off()
# Save the combined plot to a file
ggsave("~/Downloads/mytest.pdf", combined_plot,dpi = 300)
However, when I try to modify the width on the output PDF file in ggsave()
(for example by setting width=20
), the relative proportions of the plots are lost, and only the first one is extended to fill the print area (see here).
Can you advise me on how to fix this?
I am trying to merge multiple ggplot2 plots into a single picture, while retaining control over the respective height of each element. The following code works well and it generates a barplot and a curve plot that are perfectly aligned to each other (see here):
library(ggplot2)
library(grid)
library(gridExtra)
# Save plot as PDF (set to NULL initially)
pdf(file = NULL)
# Data frame for the first plot
df_1 <- data.frame(
data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1,
0.5, 0.1, 0.15, 0.5, 0.5, 0.4),
base = 1:54,
value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085,
10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042,
11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536,
7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262,
20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208,
43.54, 26.7859, 22.2176, 11.0588)
)
# First plot with ggplot
plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) +
geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) +
scale_fill_distiller(palette = 'YlGnBu') +
theme(
axis.text.x = element_text(size = 9, angle = 0, vjust = 0.5),
axis.text.y = element_text(size = 9),
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
)+
xlim(0, 55)
# Data frame for the second plot
df_2 <- data.frame(
x1 = c(4, 12, 1, 2),
x2 = c(9, 15, 24, 54),
y1 = c(0, 0, 0, 0),
y2 = c(0, 0, 0, 0),
priority = c('high', 'low', 'mid', 'high')
)
# Second plot with ggplot
plot_2 <- ggplot(df_2) +
geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority),
curvature = 1, linewidth = 0.5, ncp = 1000) +
expand_limits(y = -1) +
coord_fixed(ratio = 22, ylim = c(-1, 0)) +
scale_colour_brewer(palette = 'YlGnBu') +
theme(
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
) +
xlim(0, 55)
# List of ggplot objects
plots <- list(plot_1, plot_2) # Add as many plots as you need
# Apply a small margin to each plot to reduce extra white space
plots_adjusted <- lapply(plots, "+", theme(plot.margin = margin(0, 0, 0, 0)))
# Convert adjusted plots to gtables
grob_plots <- lapply(plots_adjusted, ggplotGrob)
# Calculate the maximum widths across all plots
max_widths <- do.call(unit.pmax, lapply(grob_plots, function(g) g$widths))
# Set each plot's widths to the calculated maximum widths
grob_plots <- lapply(grob_plots, function(g) { g$widths <- max_widths; g })
# Arrange the grobs with specific heights
combined_plot <- arrangeGrob(grobs = grob_plots, heights = unit(c(1,1), "null"), padding = unit(0, "pt"))
dev.off()
# Save the combined plot to a file
ggsave("~/Downloads/mytest.pdf", combined_plot,dpi = 300)
However, when I try to modify the width on the output PDF file in ggsave()
(for example by setting width=20
), the relative proportions of the plots are lost, and only the first one is extended to fill the print area (see here).
Can you advise me on how to fix this?
Share Improve this question asked Nov 17, 2024 at 14:41 steven_oppsteven_opp 453 bronze badges 2 |1 Answer
Reset to default 1As pointed out in the comments, combining the plots using patchwork
will keep them aligned. To control the height of each plot, you can use the height
argument in the patchwork::plot_layout
function. However, this only works if you remove the coord_fixed
argument from plot_2
.
library(ggplot2)
library(patchwork)
# Data frame for the first plot
df_1 <- data.frame(
data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1,
0.5, 0.1, 0.15, 0.5, 0.5, 0.4),
base = 1:54,
value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085,
10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042,
11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536,
7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262,
20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208,
43.54, 26.7859, 22.2176, 11.0588)
)
# First plot with ggplot
plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) +
geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) +
scale_fill_distiller(palette = 'YlGnBu') +
theme(
axis.text.x = element_text(size = 9, angle = 0, vjust = 0.5),
axis.text.y = element_text(size = 9),
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
)+
xlim(0, 55)
# Data frame for the second plot
df_2 <- data.frame(
x1 = c(4, 12, 1, 2),
x2 = c(9, 15, 24, 54),
y1 = c(0, 0, 0, 0),
y2 = c(0, 0, 0, 0),
priority = c('high', 'low', 'mid', 'high')
)
# Second plot with ggplot
plot_2 <- ggplot(df_2) +
geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority),
curvature = 1, linewidth = 0.5, ncp = 1000) +
expand_limits(y = -1) +
coord_fixed(ratio = 22, ylim = c(-1, 0)) +
scale_colour_brewer(palette = 'YlGnBu') +
theme(
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
) +
xlim(0, 55)
p <- plot_1 / plot_2
# Save the combined plot to a file
ggsave("~/Downloads/mytest.pdf",
p,
width = 20, height = 10)
If you want to adjust the heights, you can do:
p <- plot_1 / plot_2 + plot_layout(heights = c(2,1))
p
To use a large width in ggsave
, one option is to change the aspect ratio of the plot:
p <- plot_1 / plot_2 &
theme(aspect.ratio = 1/10)
ggsave("~/Downloads/mytest.pdf",
p,
width = 40, height = 10)
I am trying to merge multiple ggplot2 plots into a single picture, while retaining control over the respective height of each element. The following code works well and it generates a barplot and a curve plot that are perfectly aligned to each other (see here):
library(ggplot2)
library(grid)
library(gridExtra)
# Save plot as PDF (set to NULL initially)
pdf(file = NULL)
# Data frame for the first plot
df_1 <- data.frame(
data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1,
0.5, 0.1, 0.15, 0.5, 0.5, 0.4),
base = 1:54,
value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085,
10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042,
11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536,
7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262,
20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208,
43.54, 26.7859, 22.2176, 11.0588)
)
# First plot with ggplot
plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) +
geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) +
scale_fill_distiller(palette = 'YlGnBu') +
theme(
axis.text.x = element_text(size = 9, angle = 0, vjust = 0.5),
axis.text.y = element_text(size = 9),
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
)+
xlim(0, 55)
# Data frame for the second plot
df_2 <- data.frame(
x1 = c(4, 12, 1, 2),
x2 = c(9, 15, 24, 54),
y1 = c(0, 0, 0, 0),
y2 = c(0, 0, 0, 0),
priority = c('high', 'low', 'mid', 'high')
)
# Second plot with ggplot
plot_2 <- ggplot(df_2) +
geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority),
curvature = 1, linewidth = 0.5, ncp = 1000) +
expand_limits(y = -1) +
coord_fixed(ratio = 22, ylim = c(-1, 0)) +
scale_colour_brewer(palette = 'YlGnBu') +
theme(
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
) +
xlim(0, 55)
# List of ggplot objects
plots <- list(plot_1, plot_2) # Add as many plots as you need
# Apply a small margin to each plot to reduce extra white space
plots_adjusted <- lapply(plots, "+", theme(plot.margin = margin(0, 0, 0, 0)))
# Convert adjusted plots to gtables
grob_plots <- lapply(plots_adjusted, ggplotGrob)
# Calculate the maximum widths across all plots
max_widths <- do.call(unit.pmax, lapply(grob_plots, function(g) g$widths))
# Set each plot's widths to the calculated maximum widths
grob_plots <- lapply(grob_plots, function(g) { g$widths <- max_widths; g })
# Arrange the grobs with specific heights
combined_plot <- arrangeGrob(grobs = grob_plots, heights = unit(c(1,1), "null"), padding = unit(0, "pt"))
dev.off()
# Save the combined plot to a file
ggsave("~/Downloads/mytest.pdf", combined_plot,dpi = 300)
However, when I try to modify the width on the output PDF file in ggsave()
(for example by setting width=20
), the relative proportions of the plots are lost, and only the first one is extended to fill the print area (see here).
Can you advise me on how to fix this?
I am trying to merge multiple ggplot2 plots into a single picture, while retaining control over the respective height of each element. The following code works well and it generates a barplot and a curve plot that are perfectly aligned to each other (see here):
library(ggplot2)
library(grid)
library(gridExtra)
# Save plot as PDF (set to NULL initially)
pdf(file = NULL)
# Data frame for the first plot
df_1 <- data.frame(
data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1,
0.5, 0.1, 0.15, 0.5, 0.5, 0.4),
base = 1:54,
value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085,
10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042,
11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536,
7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262,
20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208,
43.54, 26.7859, 22.2176, 11.0588)
)
# First plot with ggplot
plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) +
geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) +
scale_fill_distiller(palette = 'YlGnBu') +
theme(
axis.text.x = element_text(size = 9, angle = 0, vjust = 0.5),
axis.text.y = element_text(size = 9),
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
)+
xlim(0, 55)
# Data frame for the second plot
df_2 <- data.frame(
x1 = c(4, 12, 1, 2),
x2 = c(9, 15, 24, 54),
y1 = c(0, 0, 0, 0),
y2 = c(0, 0, 0, 0),
priority = c('high', 'low', 'mid', 'high')
)
# Second plot with ggplot
plot_2 <- ggplot(df_2) +
geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority),
curvature = 1, linewidth = 0.5, ncp = 1000) +
expand_limits(y = -1) +
coord_fixed(ratio = 22, ylim = c(-1, 0)) +
scale_colour_brewer(palette = 'YlGnBu') +
theme(
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
) +
xlim(0, 55)
# List of ggplot objects
plots <- list(plot_1, plot_2) # Add as many plots as you need
# Apply a small margin to each plot to reduce extra white space
plots_adjusted <- lapply(plots, "+", theme(plot.margin = margin(0, 0, 0, 0)))
# Convert adjusted plots to gtables
grob_plots <- lapply(plots_adjusted, ggplotGrob)
# Calculate the maximum widths across all plots
max_widths <- do.call(unit.pmax, lapply(grob_plots, function(g) g$widths))
# Set each plot's widths to the calculated maximum widths
grob_plots <- lapply(grob_plots, function(g) { g$widths <- max_widths; g })
# Arrange the grobs with specific heights
combined_plot <- arrangeGrob(grobs = grob_plots, heights = unit(c(1,1), "null"), padding = unit(0, "pt"))
dev.off()
# Save the combined plot to a file
ggsave("~/Downloads/mytest.pdf", combined_plot,dpi = 300)
However, when I try to modify the width on the output PDF file in ggsave()
(for example by setting width=20
), the relative proportions of the plots are lost, and only the first one is extended to fill the print area (see here).
Can you advise me on how to fix this?
Share Improve this question asked Nov 17, 2024 at 14:41 steven_oppsteven_opp 453 bronze badges 2-
Have you looked at the patchwork package?
library(patchwork); plot_1 / plot_2
might do the whole thing for you and should align perfectly – Allan Cameron Commented Nov 17, 2024 at 21:08 - Unfortunately it doesn't... it aligns things, but the size stays the same, no matter how the whole print area is resized. – steven_opp Commented Nov 17, 2024 at 22:03
1 Answer
Reset to default 1As pointed out in the comments, combining the plots using patchwork
will keep them aligned. To control the height of each plot, you can use the height
argument in the patchwork::plot_layout
function. However, this only works if you remove the coord_fixed
argument from plot_2
.
library(ggplot2)
library(patchwork)
# Data frame for the first plot
df_1 <- data.frame(
data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2,
0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1,
0.5, 0.1, 0.15, 0.5, 0.5, 0.4),
base = 1:54,
value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085,
10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042,
11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536,
7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262,
20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208,
43.54, 26.7859, 22.2176, 11.0588)
)
# First plot with ggplot
plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) +
geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) +
scale_fill_distiller(palette = 'YlGnBu') +
theme(
axis.text.x = element_text(size = 9, angle = 0, vjust = 0.5),
axis.text.y = element_text(size = 9),
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
)+
xlim(0, 55)
# Data frame for the second plot
df_2 <- data.frame(
x1 = c(4, 12, 1, 2),
x2 = c(9, 15, 24, 54),
y1 = c(0, 0, 0, 0),
y2 = c(0, 0, 0, 0),
priority = c('high', 'low', 'mid', 'high')
)
# Second plot with ggplot
plot_2 <- ggplot(df_2) +
geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority),
curvature = 1, linewidth = 0.5, ncp = 1000) +
expand_limits(y = -1) +
coord_fixed(ratio = 22, ylim = c(-1, 0)) +
scale_colour_brewer(palette = 'YlGnBu') +
theme(
legend.position = 'right',
legend.spacing.x = unit(5, 'pt'),
legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10),
legend.key = element_rect(fill = NA),
axis.title.x = element_blank(),
axis.title.y = element_blank(),plot.margin = margin(0,0,0,0)
) +
guides(
colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5),
fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5)
) +
xlim(0, 55)
p <- plot_1 / plot_2
# Save the combined plot to a file
ggsave("~/Downloads/mytest.pdf",
p,
width = 20, height = 10)
If you want to adjust the heights, you can do:
p <- plot_1 / plot_2 + plot_layout(heights = c(2,1))
p
To use a large width in ggsave
, one option is to change the aspect ratio of the plot:
p <- plot_1 / plot_2 &
theme(aspect.ratio = 1/10)
ggsave("~/Downloads/mytest.pdf",
p,
width = 40, height = 10)
本文标签: rKeeping two plots vertically aligned with ggplot2gridExtraStack Overflow
版权声明:本文标题:r - Keeping two plots vertically aligned with ggplot2gridExtra - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745635578a2160427.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
library(patchwork); plot_1 / plot_2
might do the whole thing for you and should align perfectly – Allan Cameron Commented Nov 17, 2024 at 21:08