【问题标题】:R ggplot loop: in a for loop of ggplot histograms, how can you automatically set the y axis scale based on max frequency?R ggplot 循环:在 ggplot 直方图的 for 循环中,如何根据最大频率自动设置 y 轴比例?
【发布时间】:2020-07-23 15:50:06
【问题描述】:

我有以下循环来根据较大数据集 (df) 中的某些列(第 2 到 5 列)生成几个直方图:

loop.vector <- 2:5
for (i in loop.vector){
x <- df[,i]
print(ggplot(df,aes(x=x)) + geom_histogram(binwidth=1)+scale_x_continuous(breaks=seq(0,max((x),1)))
}

我想让我的 y 轴刻度自动完成,就像我对 x 轴所做的那样,它的范围在零和最大频率值之间,增量为 1。

如果我要绘制、查看并分别输入最大 y 轴值,我知道如何手动设置这些值,但我想在循环中自动执行此操作。

谢谢!

【问题讨论】:

  • 添加 scale_y_continuous(limits = c(0,max(table(x)))) 会有所帮助。
  • Duck 的评论仅在您有整数时才有效。像这样的东西:+ ylim(0, max(table(floor(df$x)))),只要你的 binwidth 保持为 1,就应该适用于连续值。

标签: r for-loop ggplot2 histogram


【解决方案1】:

回答问题:如何访问直方图的最大计数?

为了创建scale_y_continuous 命令,您在每个绘图上缺少的信息是最大计数。创建ggplot 对象后,有一个很好的方法可以访问此信息,即使用来自ggplot2 的内置ggplot_build() 函数。对于给定的绘图myPlot,以下将为您提供用于绘图中每一层的数据框列表:

ggplot_build(myPlot)$data

在您的示例中,您可以访问第一个数据框的 count 列(因为您只有一个直方图几何图层)。以下是您如何编写函数来执行您需要它执行的操作。我将使用一个可以向您展示结果的示例数据集。请注意,我还更改了您的 scale_x_continuous 行,以便能够使用 min()max() 以及 ceiling()floor() 函数的组合来容纳正数和负数:

set.seed(1234)
df <- data.frame(
  y1=rnorm(100,10,1),
  y2=rnorm(100,12,3),
  y3=rnorm(100,5,4),
  y4=rnorm(100,13,5))
    
for (i in 1:ncol(df)) {
  p <- ggplot(df, aes(df[,i])) +
    geom_histogram(alpha=0.5, color='black', fill='red', binwidth=1) +
    scale_x_continuous(breaks=seq(floor(min(df[,i])),ceiling(max(df[,i])))) +
    ggtitle(names(df)[i])
  
  # get max counts
  max_count <- max(ggplot_build(p)$data[[1]]$count)
  p <- p + scale_y_continuous(breaks=seq(0,max_count,1)) 

  print(p)
}

有没有更好的办法?

虽然这可以满足您的需求,但通常很难迭代地处理输出到图形设备的多个绘图。我建议将上述代码重新格式化为函数,然后使用lapply() 并使用cowplot 中的plot_grid() 之类的东西来显示输出。这个建议的方法在下面的代码中有详细说明:

myPlots <- function(data, column, fill_color) {
  # column = character name of column
  p <- ggplot(data, aes_string(x=column)) +
    geom_histogram(fill='red', binwidth=1, alpha=0.5, color='black') +
    scale_x_continuous(breaks=seq(floor(min(data[column])), ceiling(max(data[column])),1)) +
    ggtitle(column)
  
  max_count <- max(ggplot_build(p)$data[[1]]$count)
  p <- p + scale_y_continuous(breaks=seq(0,max_count,1))
  return(p)
}

library(cowplot)

plotList <- lapply(names(df), myPlots, data=df)
plot_grid(plotlist = plotList)

【讨论】:

    【解决方案2】:

    想通了 - 我的值是整数,所以最终起作用的是 Duck 响应的变体。见下文:

    loop.vector <- 2:5
    for (i in loop.vector){
    x <- df[,i]
    print(ggplot(df,aes(x=x)) + geom_histogram(binwidth=1)+scale_x_continuous(breaks=seq(0,max((x),1)))+scale_y_continuous(breaks=seq(0,max(table(x)),1)))
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 2019-12-17
      • 1970-01-01
      • 2014-04-06
      相关资源
      最近更新 更多