是否有一种简单的方法可以在“堆叠”条形图中标记单个“块”,如下所示。我希望标签位于每个区块的顶部附近,但我的最新方法导致以某种方式交换美国和墨西哥的文本,如下所示。
寻找解决方案,我只找到了必须在外部预先计算文本的y
值的方法,除了额外的逻辑之外,它还会带来控制顺序的问题。哪些块堆叠...
我还发现了这个stackoverflow question我在geom="text"
中使用stat_bin
的想法(见下面的代码)
这是一个精简的代码片段,用于说明我当前的方法。 我不一定要修复这个片段,标签堆栈条形图区域的任何通用习惯用法都可以!
编辑:(鉴于到目前为止这个问题的两个答案)
我想强调我宁愿解决方案并不意味着预先计算文本的y位置。
# sample data source
df.StackData <- data.frame(
QType = c("A4-1", "A4-1", "A4-1", "B3", "B3", "B3"),
Country = c("Canada", "USA", "Mexico", "Canada", "USA", "Mexico"),
NbOfCases = c(1000, 1320, 380, 400, 1000, 812),
AvgRate = c(17.2, 11.4, 44.21, 17.3, 15.3, 39.7),
Comment = c("Can", "US", "Mex", "Can", "US", "Mex")
)
和ggplot调用。 它生成上面显示的图形,标签交换奇怪(也是一个额外的图例,'虽然这个传奇问题很容易处理;我在准备这个问题时就注意到了这一点。)
ggplot(data=df.StackData,
aes(x=QType, y=NbOfCases, fill=Country))+
geom_bar(stat="identity", width=1) +
stat_bin(geom="text", aes(label=paste("R coef =",
formatC(AvgRate, format="f", digits=3),
"(", Comment, ")" ),
vjust=1.5, size=3
)
)
我的初步尝试将geom_text()添加到图形中,如下所示,但当然y值是错误的(相对于图形的最底层而不是单个块底部的文本)... < / p>
... +
geom_text(mapping=aes(x=QType, y=NbOfCases,
label=paste("R coef =",
formatC(AvgRate, format="f", digits=3),
"(", Comment, ")" ),
vjust=1.5),
size=3)
答案 0 :(得分:2)
这是一个解决方案。这里有两件事。首先,您应reorder
将data.frame
的级别设置为与数据df.StackData
中的订单相同的订单。其次,通过计算数据的累积总和,创建另一个data.frame
来计算y-position
。
# reorder levels of factor to the same order as found in data
df.StackData$Country <- factor(df.StackData$Country,
levels=c("Canada", "USA", "Mexico"), ordered=TRUE)
p <- ggplot(data=df.StackData, aes(x=QType, fill=Country))
p <- p + geom_bar(aes(weights=NbOfCases))
# compute corresponding y-axis positions by cumulative sum
require(plyr)
df <- ddply(df.StackData, .(QType), function(x) {
x$NbOfCases <- cumsum(x$NbOfCases)
x
})
# then use geom_text with data = df (the newly created data)
p + geom_text(data = df, aes(x=QType, y=NbOfCases,
label=paste("R coef =",
formatC(AvgRate, format="f", digits=3),
"(", Comment, ")" ), vjust=1.5), size=3)
编辑:如果您不想自己计算y-pos,则必须使用stat_bin
。只需重新排序列Country
的级别,它就可以了:
# data
df.StackData <- data.frame(
QType = c("A4-1", "A4-1", "A4-1", "B3", "B3", "B3"),
Country = c("Canada", "USA", "Mexico", "Canada", "USA", "Mexico"),
NbOfCases = c(1000, 1320, 380, 400, 1000, 812),
AvgRate = c(17.2, 11.4, 44.21, 17.3, 15.3, 39.7),
Comment = c("Can", "US", "Mex", "Can", "US", "Mex")
)
# just add this: reorder the level
df.StackData$Country <- factor(df.StackData$Country,
levels=c("Canada", "USA", "Mexico"), ordered=TRUE)
# your code again using stat_bin (just changed the width to 0.75)
ggplot(data=df.StackData,
aes(x=QType, y=NbOfCases, fill=Country))+
geom_bar(stat="identity", width=.75) +
stat_bin(geom="text", size=4, aes(label=paste("R coef =",
formatC(AvgRate, format="f", digits=3),
"(", Comment, ")" ),
vjust=1.5))
答案 1 :(得分:2)
这是一个解决方案
df2 = ddply(df.StackData, .(QType), transform,
pos = cumsum(NbOfCases) - 0.5 * NbOfCases)
ggplot(data = df2, aes(x = QType, y = NbOfCases, fill = Country)) +
geom_bar(stat = "identity") +
geom_text(aes(y = pos, label = paste("R coef =",
formatC(AvgRate, format="f", digits=3), "(", Comment, ")" ))
)
答案 2 :(得分:1)
这是一个替代方案 - 因为默认情况下您的因子将按字母顺序排序,我建议您重新排序数据帧以匹配此数据,而不是重新排序因子以匹配数据帧的顺序。在我看来,这将允许更通用的解决方案。你得到一个你不想要的传奇的唯一原因是你的大小在aes
之内 - 我已经解决了以下问题。
使用您的数据:
df.StackData <- with(df.StackData, df.StackData[order(Country),])
然后您可以将原始解决方案与stat_bin
一起使用。我用一些更复杂的数据集对它进行了测试,以检查它是否有效:
df.StackData <- data.frame(
QType = rep(c("A4-1","B3"), each = 6),
Country = rep(c("Canada", "USA", "Mexico", "UK", "Sweden", "Australia"), times = 2),
NbOfCases = c(1000, 1320, 380, 400, 1000, 812, 542, 531, 674, 328, 795, 721),
AvgRate = c(17.2, 11.4, 44.21, 17.3, 15.3, 39.7, 21.1, 25.3, 24.1, 31.3, 38.4, 36.1),
Comment = rep(c("Can", "US", "Mex", "UK", "Aus", "Swe"), times = 2)
)
没有排序:
ggplot(data=df.StackData,
aes(x=QType, y=NbOfCases, fill=Country))+
geom_bar(stat="identity", width=1) +
stat_bin(geom="text", aes(label=paste("R coef =", formatC(AvgRate, format="f", digits=3),
"(", Comment, ")" ), vjust = 1),size=3)
geom_text(aes(label = Comment), stat="identity")
排序后:
df.StackData&lt; - with(df.StackData,df.StackData [order(Country),])
答案 3 :(得分:1)
要删除额外的图例,您可以使用show_guide=FALSE
。在您的示例中:
ggplot(data=df.StackData,
aes(x=QType, y=NbOfCases, fill=Country))+
geom_bar(stat="identity", width=.75) +
stat_bin(geom="text", size=4, aes(label=paste("R coef =",
formatC(AvgRate, format="f", digits=3),
"(", Comment, ")" ),
vjust=1.5), show_guide=FALSE)