R 中带有线图叠加的并排条形图
Side-by-side barplot with line plot overlay in R
好的,我在数据框中有数据,我想使用两个变量 y1 和 y2 并创建一个并排的条形图比较,其中条形高度等于 y1 和 y2 中每个元素的值。然后我想用两个变量的比率叠加一条线,这些值的第二个 y 轴。我的具体问题是我无法适当地缩放第二个 y 轴(因此在我的示例中降低了比率,以便它落在图表中)。
更一般地说,我对条形图在基本图形中的工作原理知之甚少,感觉我必须自己破解它 - 尽管阅读了多篇关于这个的帖子,以及一些大多不了解的教程'进入足够的细节。有些事情我不清楚; A. 从 df 中的数据到适合条形图的数据的最佳方法是什么 - 是否必须像我在这里那样将数据转置到条形图矩阵中,为什么? B. 什么决定了条形的 x 轴位置(即什么是 "myplot" 对象以及如何确定值?有没有办法更优雅地设置我的 points/lines 的 x 位置?我不得不使用有点难看的编码来强制它,因为我真的不明白它是如何工作的。C. 不确定我将如何从我的 df 中的行名称(如果有的话)到我的栏中的类别(x 轴)名称图表。我有点不得不在我的绘图参数中强制执行此操作。D. 是否有关于条形图的明确讨论在条形图的内部工作原理上更深入一点?
rm(list = ls(all = TRUE))
df <- data.frame(y1 = runif(10, min=0, max=1), y2 = runif(10, min=1, max=2))
df$ratio <- df$y2/df$y1
df
barmatrix <- t(df[,1:2])
barmatrix
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3), cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=c("0","1","2","3","4","5","6","7","8","9"))
lines(x = myplot[1, ] + 0.5, y = df$ratio/3)
points(x = myplot[1, ] + 0.5, y = df$ratio/3)
axis(4, ylim = c(0, 20))
您可以按比例缩小 10 以适合绘图,然后在添加的轴上缩放数字(即标签)。
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3), cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=c("0","1","2","3","4","5","6","7","8","9"))
lines(x = myplot[1, ] + 0.5, y = df$ratio/10)
points(x = myplot[1, ] + 0.5, y = df$ratio/10)
axis(4, at=0:6/2,labels=0:6*5)
更新:
动态缩放
rm(list = ls(all = TRUE))
df <- data.frame(y1 = runif(10, min=0, max=1), y2 = runif(10, min=1, max=2))
df$ratio <- df$y2/df$y1
df
barmatrix <- t(df[,1:2])
barmatrix
sf <- max(pretty(df$ratio/3)) # scale factor
# divide by 3 since that is your limit on the barplot ylim
sf
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3), cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=c("0","1","2","3","4","5","6","7","8","9"))
lines(x = myplot[1, ] + 0.5, y = df$ratio/sf)
points(x = myplot[1, ] + 0.5, y = df$ratio/sf)
axis(4, at=0:3,labels=0:3*sf)
更新 2:回答您的更多问题。
矩阵 myplot
的每一行都有每个系列的 x 位置。您可以求每列的平均值,以便更灵活地找到多个系列的中点。
你也可以直接用row.names
标注。
并且使用 type="o"
您可以一次绘制线和点。
rm(list = ls(all = TRUE))
df <- data.frame(y1 = runif(10, min=0, max=1), y2 = runif(10, min=1, max=2))
df$ratio <- df$y2/df$y1
row.names(df) <- LETTERS[1:10]
df
barmatrix <- t(df[,1:2])
barmatrix
sf <- max(pretty(df$ratio/3)) # scale factor
# divide by 3 since that is your limit on the barplot ylim
sf
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3),
cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=row.names(df))
lines(x = colSums(myplot)/nrow(myplot), y = df$ratio/sf,type="o")
axis(4, at=0:3,labels=0:3*sf)
好的,我在数据框中有数据,我想使用两个变量 y1 和 y2 并创建一个并排的条形图比较,其中条形高度等于 y1 和 y2 中每个元素的值。然后我想用两个变量的比率叠加一条线,这些值的第二个 y 轴。我的具体问题是我无法适当地缩放第二个 y 轴(因此在我的示例中降低了比率,以便它落在图表中)。
更一般地说,我对条形图在基本图形中的工作原理知之甚少,感觉我必须自己破解它 - 尽管阅读了多篇关于这个的帖子,以及一些大多不了解的教程'进入足够的细节。有些事情我不清楚; A. 从 df 中的数据到适合条形图的数据的最佳方法是什么 - 是否必须像我在这里那样将数据转置到条形图矩阵中,为什么? B. 什么决定了条形的 x 轴位置(即什么是 "myplot" 对象以及如何确定值?有没有办法更优雅地设置我的 points/lines 的 x 位置?我不得不使用有点难看的编码来强制它,因为我真的不明白它是如何工作的。C. 不确定我将如何从我的 df 中的行名称(如果有的话)到我的栏中的类别(x 轴)名称图表。我有点不得不在我的绘图参数中强制执行此操作。D. 是否有关于条形图的明确讨论在条形图的内部工作原理上更深入一点?
rm(list = ls(all = TRUE))
df <- data.frame(y1 = runif(10, min=0, max=1), y2 = runif(10, min=1, max=2))
df$ratio <- df$y2/df$y1
df
barmatrix <- t(df[,1:2])
barmatrix
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3), cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=c("0","1","2","3","4","5","6","7","8","9"))
lines(x = myplot[1, ] + 0.5, y = df$ratio/3)
points(x = myplot[1, ] + 0.5, y = df$ratio/3)
axis(4, ylim = c(0, 20))
您可以按比例缩小 10 以适合绘图,然后在添加的轴上缩放数字(即标签)。
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3), cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=c("0","1","2","3","4","5","6","7","8","9"))
lines(x = myplot[1, ] + 0.5, y = df$ratio/10)
points(x = myplot[1, ] + 0.5, y = df$ratio/10)
axis(4, at=0:6/2,labels=0:6*5)
更新: 动态缩放
rm(list = ls(all = TRUE))
df <- data.frame(y1 = runif(10, min=0, max=1), y2 = runif(10, min=1, max=2))
df$ratio <- df$y2/df$y1
df
barmatrix <- t(df[,1:2])
barmatrix
sf <- max(pretty(df$ratio/3)) # scale factor
# divide by 3 since that is your limit on the barplot ylim
sf
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3), cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=c("0","1","2","3","4","5","6","7","8","9"))
lines(x = myplot[1, ] + 0.5, y = df$ratio/sf)
points(x = myplot[1, ] + 0.5, y = df$ratio/sf)
axis(4, at=0:3,labels=0:3*sf)
更新 2:回答您的更多问题。
矩阵 myplot
的每一行都有每个系列的 x 位置。您可以求每列的平均值,以便更灵活地找到多个系列的中点。
你也可以直接用row.names
标注。
并且使用 type="o"
您可以一次绘制线和点。
rm(list = ls(all = TRUE))
df <- data.frame(y1 = runif(10, min=0, max=1), y2 = runif(10, min=1, max=2))
df$ratio <- df$y2/df$y1
row.names(df) <- LETTERS[1:10]
df
barmatrix <- t(df[,1:2])
barmatrix
sf <- max(pretty(df$ratio/3)) # scale factor
# divide by 3 since that is your limit on the barplot ylim
sf
par(mfrow = c(1,1))
myplot <- barplot(barmatrix, main="My Barchart", ylab = "Values", ylim = c(0,3),
cex.lab = 1.5, cex.main = 1.4, beside=TRUE, names.arg=row.names(df))
lines(x = colSums(myplot)/nrow(myplot), y = df$ratio/sf,type="o")
axis(4, at=0:3,labels=0:3*sf)