代码之家  ›  专栏  ›  技术社区  ›  John Gagnon

如何在ggplot2中指定与轴标签无关的图形大小

  •  11
  • John Gagnon  · 技术社区  · 8 年前

    假设我有一个数据框,想要绘制一个图

    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")
    

    enter image description here

    问题是,我想指定绘图本身的尺寸,但与轴标签无关,以便下面指定的绘图在轴的绝对长度方面具有相同的大小和尺寸。

    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")
    

    enter image description here

    下面是一个更接近我想要的轴长度的绘图示例:

    enter image description here

    唯一的问题是,通过改变纵横比,我最终挤压了y轴,使x轴在长度上更接近均匀。。。

    5 回复  |  直到 8 年前
        1
  •  5
  •   Maurits Evers    6 年前

    使用 ggplotGrob . 类似这样:

    g1 <- ggplot(...)
    g2 <- ggplot(...)
    
    g1grob <- ggplotGrob(g1)
    g2grob <- ggplotGrob(g2)
    
    grid.arrange(g1grob, g2grob)
    
        2
  •  4
  •   Maurits Evers    8 年前

    我真的不明白你在找什么,所以这有点像是在暗中捅一刀。

    可以使用相同的比例显示两个绘图 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);
    

    enter image description here

    ggplot(df, aes(x = Species, y = value)) + 
        geom_boxplot() + theme(aspect.ratio = 1) + 
        facet_wrap(~ L1, scales = "free_y");
    

    enter image description here

    通过使用指定列数或行数,可以调整镶嵌面的网格布局 nrow ncol .

    例如,对于两个图的垂直放置,你可以这样做

    ggplot(df, aes(x = Species, y = value)) + 
        geom_boxplot() + theme(aspect.ratio = 1) + 
        facet_wrap(~ L1, ncol = 1, scales = "free_y");
    

    enter image description here

        3
  •  3
  •   user7433963    7 年前

    我观察到同样的行为,当在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)
    

    绘图区域随标签长度变化

        4
  •  3
  •   S.T.    7 年前

    ggplot2, arrange multiple plots, all the same size, no gaps in between

    因此,基本上,您希望绘制区域(x轴和y轴内的区域)对于多个图形是相同的。这也是我在使用ggplot2时发现的一个问题。一种解决方案是通过 align_plots() cowplot包中的函数:

    `allplotslist <- align_plots(plot1, plot2, plot3, align = "hv")`
    

    这使得所有绘图的绘图区域大小相同。 然后你可以使用 ggdraw()

    `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]])`
    

    希望这有帮助, 干杯

        5
  •  0
  •   marina    6 年前

    我知道,这不是一个非常普遍的解决方案。我需要30个(或更多)单独的地块。在一个单独的底层grob中观察到的数量,因此x轴的大小必须固定。 希望这能帮助别人