R ggplot 循环:在 ggplot 直方图的 for 循环中,如何根据最大频率自动设置 y 轴刻度?
R ggplot loop: in a for loop of ggplot histograms, how can you automatically set the y axis scale based on max frequency?
我有以下循环来根据较大数据集 (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)))
}
我希望像 x 轴一样自动完成 y 轴刻度,它的范围在零和最大频率值之间,以 1 为增量。
我知道如何手动设置这些值,如果我要绘图,看看它,并分别输入最大 y 轴值,但我想在循环中自动执行此操作。
谢谢!
回答问题:如何访问直方图的最大计数?
为了创建您的 scale_y_continuous
命令,您在每个图上缺少的信息是最大计数数。创建 ggplot
对象后,有一种访问此信息的好方法,即使用 ggplot2
中的内置 ggplot_build()
函数。对于给定的绘图,myPlot
,以下将为您提供用于绘图中每一层的数据帧列表:
ggplot_build(myPlot)$data
在您的示例中,您可以访问第一个数据框的 count
列(因为您只有一个直方图 geom 图层)。以下是如何编写函数来执行您需要它执行的操作。我将使用一个示例数据集来向您展示结果。请注意,我还更改了 scale_x_continuous
行,以便通过使用 min()
、max()
以及 ceiling()
和 [= 的组合来容纳正数和负数23=] 函数:
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)
弄清楚了 - 我的值是整数,所以最终起作用的是 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)))
}
我有以下循环来根据较大数据集 (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)))
}
我希望像 x 轴一样自动完成 y 轴刻度,它的范围在零和最大频率值之间,以 1 为增量。
我知道如何手动设置这些值,如果我要绘图,看看它,并分别输入最大 y 轴值,但我想在循环中自动执行此操作。
谢谢!
回答问题:如何访问直方图的最大计数?
为了创建您的 scale_y_continuous
命令,您在每个图上缺少的信息是最大计数数。创建 ggplot
对象后,有一种访问此信息的好方法,即使用 ggplot2
中的内置 ggplot_build()
函数。对于给定的绘图,myPlot
,以下将为您提供用于绘图中每一层的数据帧列表:
ggplot_build(myPlot)$data
在您的示例中,您可以访问第一个数据框的 count
列(因为您只有一个直方图 geom 图层)。以下是如何编写函数来执行您需要它执行的操作。我将使用一个示例数据集来向您展示结果。请注意,我还更改了 scale_x_continuous
行,以便通过使用 min()
、max()
以及 ceiling()
和 [= 的组合来容纳正数和负数23=] 函数:
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)
弄清楚了 - 我的值是整数,所以最终起作用的是 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)))
}