[英]How to control ordering of stacked bar chart using identity on ggplot2
Using this dummy data.frame
使用这个虚拟data.frame
ts <- data.frame(x=1:3, y=c("blue", "white", "white"), z=c("one", "one", "two"))
I try and plot with category "blue" on top.我尝试在顶部绘制类别“蓝色”。
ggplot(ts, aes(z, x, fill=factor(y, levels=c("blue","white" )))) + geom_bar(stat = "identity")
gives me "white" on top.在上面给我“白色”。 and和
ggplot(ts, aes(z, x, fill=factor(y, levels=c("white", "blue")))) + geom_bar(stat = "identity")
reverses the colors, but still gives me "white" on top.反转颜色,但仍然在顶部给我“白色”。 How can I get "blue" on top?我怎样才能在顶部获得“蓝色”?
For what it is worth, in ggplot2 version 2.2.1 the order of the stack is no longer determined by the row order in the data.frame.值得一提的是,在 ggplot2 版本 2.2.1 中,堆栈的顺序不再由 data.frame 中的行顺序决定。 Instead, it matches the order of the legend as determined by the order of levels in the factor.相反,它匹配由因子中的级别顺序确定的图例顺序。
d <- data.frame(
y=c(0.1, 0.2, 0.7),
cat = factor(c('No', 'Yes', 'NA'), levels = c('NA', 'Yes', 'No')))
# Original order
p1 <- ggplot(d, aes(x=1, y=y, fill=cat)) +
geom_bar(stat='identity')
# Change order of rows
p2 <- ggplot(d[c(2, 3, 1), ], aes(x=1, y=y, fill=cat)) +
geom_bar(stat='identity')
# Change order of levels
d$cat2 <- relevel(d$cat, 'Yes')
p3 <- ggplot(d, aes(x=1, y=y, fill=cat2)) +
geom_bar(stat='identity')
grid.arrange(p1, p2, p3, ncol=3)
I've struggled with the same issue before.我之前一直在努力解决同样的问题。 It appears that ggplot stacks the bars based on their appearance in the dataframe.看来 ggplot 根据条形在数据框中的外观堆叠条形。 So the solution to your problem is to sort your data by the fill factor in the reverse order you want it to appear in the legend: bottom item on top of the dataframe, and top item on bottom:因此,您的问题的解决方案是按填充因子按您希望它出现在图例中的相反顺序对数据进行排序:数据框顶部的底部项目和底部的顶部项目:
ggplot(ts[order(ts$y, decreasing = T),],
aes(z, x, fill=factor(y, levels=c("blue","white" )))) +
geom_bar(stat = "identity")
Using sample data, I created three plots with different orderings of the dataframe, I thought that more fill-variables would make things a bit clearer.使用示例数据,我创建了三个具有不同数据框顺序的图,我认为更多的填充变量会使事情更清晰一些。
set.seed(123)
library(gridExtra)
df <- data.frame(x=rep(c(1,2),each=5),
fill_var=rep(LETTERS[1:5], 2),
y=1)
#original order
p1 <- ggplot(df, aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Original dataframe")
#random order
p2 <- ggplot(df[sample(1:10),],aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Random order")
#legend checks out, sequence wird
#reverse order
p3 <- ggplot(df[order(df$fill_var,decreasing=T),],
aes(x=x,y=y,fill=fill_var))+
geom_bar(stat="identity") + labs(title="Reverse sort by fill")
plots <- list(p1,p2,p3)
do.call(grid.arrange,plots)
Use the group
aethetic in the ggplot()
call.在ggplot()
调用中使用group
美学。 This ensures that all layers are stacked in the same way.这确保所有层都以相同的方式堆叠。
series <- data.frame(
time = c(rep(1, 4),rep(2, 4), rep(3, 4), rep(4, 4)),
type = rep(c('a', 'b', 'c', 'd'), 4),
value = rpois(16, 10)
)
ggplot(series, aes(time, value, group = type)) +
geom_col(aes(fill = type)) +
geom_text(aes(label = type), position = "stack")
Messing with your data in order to make a graph look nice seems like a bad idea.为了使图表看起来更漂亮而使用您的数据似乎是个坏主意。 Here's an alternative that works for me when using position_fill()
:这是使用position_fill()
时对我有用的替代方法:
ggplot(data, aes(x, fill = fill)) + geom_bar(position = position_fill(reverse = TRUE))
The reverse = TRUE
argument flips the order of the stacked bars. reverse = TRUE
参数翻转堆叠条的顺序。 This works in position_stack
also.这也适用于position_stack
。
I have the exactly same problem today.我今天遇到了完全相同的问题。 You can get blue
on top by using order=-as.numeric()
:您可以使用order=-as.numeric()
获得blue
:
ggplot(ts,
aes(z, x, fill=factor(y, levels=c("blue","white")), order=-as.numeric(y))) +
geom_bar(stat = "identity")
I had a similar issue and got around by changing the level of the factor.我有一个类似的问题,并通过改变因子的水平来解决。 thought I'd share the code:以为我会分享代码:
library(reshape2)
library(ggplot2)
group <- c(
"1",
"2-4",
"5-9",
"10-14",
"15-19",
"20-24",
"25-29",
"30-34",
"35-39",
"40-44",
"45-49"
)
xx <- factor(group, levels(factor(group))[c(1, 4, 11, 2, 3, 5:10)])
method.1 <- c(36, 14, 8, 8, 18, 1, 46, 30, 62, 34, 34)
method.2 <- c(21, 37, 45, 42, 68, 41, 16, 81, 51, 62, 14)
method.3 <- c(37, 46, 18, 9, 16, 79, 46, 45, 70, 42, 28)
elisa.neg <- c(12, 17, 18, 6, 19, 14, 13, 13, 7, 4, 1)
elisa.eq <- c(3, 6, 3, 14, 1, 4, 11, 13, 5, 3, 2)
test <- data.frame(person = xx,
"Mixture Model" = method.1,
"Censoring" = method.3,
"ELISA neg" = elisa.neg,
"ELISA eqiv" = elisa.eq)
melted <- melt(test, "person")
melted$cat <- ifelse(melted$variable == "Mixture.Model", "1",
ifelse(melted$variable == "Censoring", "2", "3"))
melted$variable = factor(melted$variable, levels = levels(melted$variable)[c(1, 2, 4,3 )]) ## This did the trick of changing the order
ggplot(melted, aes(x = cat, y = value, fill = variable)) +
geom_bar(stat = 'identity') + facet_wrap(~ person) +
theme(axis.ticks.x=element_blank(),
axis.text.x=element_blank()) +
labs(title = "My Title",
y = "Per cent", x = "Age Group", fill = "")
(Sorry, this is my data, I didn't reproduce using the data from the original post, hope it's ok!) (抱歉,这是我的数据,我没有使用原帖中的数据进行复制,希望没问题!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.