如何在 ggplot2 中独立于轴标签指定图形的大小
How to specify the size of a graph in ggplot2 independent of axis labels
说我有一个数据框,想画一个图
df <- melt(iris)
p <- ggplot(data = df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1)
然后我想使用 ggsave() 保存此图的 pdf
ggsave(plot = p, width = 3, height = 3, dpi = 300, filename = "not squished axis.pdf")
问题是我想指定图本身的尺寸但独立于轴标签,以便下面指定的图在轴的绝对长度方面具有相同的大小和尺寸。
q <- ggplot(data = df, aes(x = Species, y = (value)*10000000)) +
geom_boxplot() + theme(aspect.ratio = 1)
ggsave(plot = q, width = 3, height = 3, dpi = 300, filename = "squished axis.pdf")
有没有办法轻松做到这一点?
这是一个在轴长度方面更接近我想要的图的示例:
唯一的问题是,通过改变纵横比,我最终挤压了 y 轴,使 x 轴的长度更接近均匀...
我不太明白你在追求什么,所以这有点摸不着头脑。
您可以使用相同比例显示两个图 facet_wrap
:
# Your sample data
df <- list(
one = melt(iris),
two = with(melt(iris), cbind.data.frame(Species, variable, value * 1000)));
df <- melt(df);
ggplot(df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1) +
facet_wrap(~ L1);
或者允许每个方面的 y 尺度自由变化。
ggplot(df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1) +
facet_wrap(~ L1, scales = "free_y");
您可以通过使用 nrow
和 ncol
指定列数或行数来调整构面的网格布局。
因此,例如,对于两个图的垂直放置,您可以这样做
ggplot(df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1) +
facet_wrap(~ L1, ncol = 1, scales = "free_y");
使用ggplotGrob
。像这样:
g1 <- ggplot(...)
g2 <- ggplot(...)
g1grob <- ggplotGrob(g1)
g2grob <- ggplotGrob(g2)
grid.arrange(g1grob, g2grob)
我观察到相同的行为,当在 x 轴上使用垂直标签时,这种行为会被放大。
使用以下代码,绘图区域会因标签长度的不同而有所不同。
library(ggplot2)
library(gridExtra)
df1 <- data.frame(x_label=c(rep("one", 10), rep("two", 20), rep("three", 30)))
plt1 <- ggplot(data.frame(df1), aes(x=x_label)) +
ggtitle("My test data percentages") +
labs(x="", y="Percentage" ) +
geom_bar(aes(y = ( (..count..)/sum(..count..) * 100.0) ), width=1) +
expand_limits(y=c(0.0, 50.0)) +
theme_light() +
theme(plot.title = element_text(hjust = 0.5), axis.text.x=element_text(angle=90, hjust=1, size=8), panel.spacing.x=unit(0.5, "lines"))
df2 <- data.frame(x_label=c(rep("very long label one", 10), rep("very long label two", 20), rep("very long label three", 30)))
plt2 <- ggplot(data.frame(df2), aes(x=x_label)) +
ggtitle("My test data percentages") +
labs(x="", y="Percentage" ) +
geom_bar(aes(y = ( (..count..)/sum(..count..) * 100.0) ), width=1) +
expand_limits(y=c(0.0, 50.0)) +
theme_light() +
theme(plot.title = element_text(hjust = 0.5), axis.text.x=element_text(angle=90, hjust=1, size=8), panel.spacing.x=unit(0.5, "lines"))
gridExtra::grid.arrange(plt1, plt2, nrow=1)
绘图区域随标签长度变化
回答你的问题有点晚,但我认为这个 post 可能会有所帮助:ggplot2, arrange multiple plots, all the same size, no gaps in between
所以基本上您希望多个图形的绘图区域(x 轴和 y 轴内的区域)相同。这也是我在使用 ggplot2 时发现的一个问题。一种解决方案是通过 cowplot 包中的 align_plots()
函数传递每个图:
`allplotslist <- align_plots(plot1, plot2, plot3, align = "hv")`
这使得所有绘图的绘图区域大小相同。
然后您可以使用 ggdraw()
(也来自 cowplot)将绘图放入同一个图中,指定每个绘图的坐标,并将大小指定为(x 坐标,y 坐标,宽度,高度):
`final_figure <- ggdraw() + draw_plot(allplotslist[[1]], 0,0,0.3,0.3) +
draw_plot(allplotslist[[2]], 0,0.3,0.3,0.3) + draw_plot(allplotslist[[3]], 0,0,0.6,0.3)`
您还可以使用其他函数,如 plot_grid()
(来自 cowplot)或 grid.arrange()
(来自 gridExtra 包)来绘制大小相同的新图:
`grid.arrange(allplotslist[[1]], allplotslist[[2]], allplotslist[[3]])`
希望对您有所帮助,
干杯
我觉得有点晚了,但我通过修复标签的 nchar 解决了这个问题。
这不是一个非常通用的解决方案,我知道。我需要 30 个(或更多)分离图。在单独的底层 grob 中的观察数量,因此 x 轴的大小必须固定。
希望这会对某人有所帮助
说我有一个数据框,想画一个图
df <- melt(iris)
p <- ggplot(data = df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1)
然后我想使用 ggsave() 保存此图的 pdf
ggsave(plot = p, width = 3, height = 3, dpi = 300, filename = "not squished axis.pdf")
问题是我想指定图本身的尺寸但独立于轴标签,以便下面指定的图在轴的绝对长度方面具有相同的大小和尺寸。
q <- ggplot(data = df, aes(x = Species, y = (value)*10000000)) +
geom_boxplot() + theme(aspect.ratio = 1)
ggsave(plot = q, width = 3, height = 3, dpi = 300, filename = "squished axis.pdf")
有没有办法轻松做到这一点?
这是一个在轴长度方面更接近我想要的图的示例:
唯一的问题是,通过改变纵横比,我最终挤压了 y 轴,使 x 轴的长度更接近均匀...
我不太明白你在追求什么,所以这有点摸不着头脑。
您可以使用相同比例显示两个图 facet_wrap
:
# Your sample data
df <- list(
one = melt(iris),
two = with(melt(iris), cbind.data.frame(Species, variable, value * 1000)));
df <- melt(df);
ggplot(df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1) +
facet_wrap(~ L1);
或者允许每个方面的 y 尺度自由变化。
ggplot(df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1) +
facet_wrap(~ L1, scales = "free_y");
您可以通过使用 nrow
和 ncol
指定列数或行数来调整构面的网格布局。
因此,例如,对于两个图的垂直放置,您可以这样做
ggplot(df, aes(x = Species, y = value)) +
geom_boxplot() + theme(aspect.ratio = 1) +
facet_wrap(~ L1, ncol = 1, scales = "free_y");
使用ggplotGrob
。像这样:
g1 <- ggplot(...)
g2 <- ggplot(...)
g1grob <- ggplotGrob(g1)
g2grob <- ggplotGrob(g2)
grid.arrange(g1grob, g2grob)
我观察到相同的行为,当在 x 轴上使用垂直标签时,这种行为会被放大。
使用以下代码,绘图区域会因标签长度的不同而有所不同。
library(ggplot2)
library(gridExtra)
df1 <- data.frame(x_label=c(rep("one", 10), rep("two", 20), rep("three", 30)))
plt1 <- ggplot(data.frame(df1), aes(x=x_label)) +
ggtitle("My test data percentages") +
labs(x="", y="Percentage" ) +
geom_bar(aes(y = ( (..count..)/sum(..count..) * 100.0) ), width=1) +
expand_limits(y=c(0.0, 50.0)) +
theme_light() +
theme(plot.title = element_text(hjust = 0.5), axis.text.x=element_text(angle=90, hjust=1, size=8), panel.spacing.x=unit(0.5, "lines"))
df2 <- data.frame(x_label=c(rep("very long label one", 10), rep("very long label two", 20), rep("very long label three", 30)))
plt2 <- ggplot(data.frame(df2), aes(x=x_label)) +
ggtitle("My test data percentages") +
labs(x="", y="Percentage" ) +
geom_bar(aes(y = ( (..count..)/sum(..count..) * 100.0) ), width=1) +
expand_limits(y=c(0.0, 50.0)) +
theme_light() +
theme(plot.title = element_text(hjust = 0.5), axis.text.x=element_text(angle=90, hjust=1, size=8), panel.spacing.x=unit(0.5, "lines"))
gridExtra::grid.arrange(plt1, plt2, nrow=1)
绘图区域随标签长度变化
回答你的问题有点晚,但我认为这个 post 可能会有所帮助:ggplot2, arrange multiple plots, all the same size, no gaps in between
所以基本上您希望多个图形的绘图区域(x 轴和 y 轴内的区域)相同。这也是我在使用 ggplot2 时发现的一个问题。一种解决方案是通过 cowplot 包中的 align_plots()
函数传递每个图:
`allplotslist <- align_plots(plot1, plot2, plot3, align = "hv")`
这使得所有绘图的绘图区域大小相同。
然后您可以使用 ggdraw()
(也来自 cowplot)将绘图放入同一个图中,指定每个绘图的坐标,并将大小指定为(x 坐标,y 坐标,宽度,高度):
`final_figure <- ggdraw() + draw_plot(allplotslist[[1]], 0,0,0.3,0.3) +
draw_plot(allplotslist[[2]], 0,0.3,0.3,0.3) + draw_plot(allplotslist[[3]], 0,0,0.6,0.3)`
您还可以使用其他函数,如 plot_grid()
(来自 cowplot)或 grid.arrange()
(来自 gridExtra 包)来绘制大小相同的新图:
`grid.arrange(allplotslist[[1]], allplotslist[[2]], allplotslist[[3]])`
希望对您有所帮助, 干杯
我觉得有点晚了,但我通过修复标签的 nchar 解决了这个问题。 这不是一个非常通用的解决方案,我知道。我需要 30 个(或更多)分离图。在单独的底层 grob 中的观察数量,因此 x 轴的大小必须固定。 希望这会对某人有所帮助