更改 ggplot2 barplot 中闪避条的顺序
Posted
技术标签:
【中文标题】更改 ggplot2 barplot 中闪避条的顺序【英文标题】:Changing the order of dodged bars in ggplot2 barplot 【发布时间】:2010-12-15 20:17:21 【问题描述】:我有一个数据框df.all
,我使用下面的代码将它绘制在一个带有 ggplot2 的条形图中。我想让它翻转被闪避的条形图的顺序。也就是说,标有“单数”的条位于标有“复数”的条之前。
ggplot(df.all, aes(gram, V1, fill=number)) +
geom_bar(stat="identity", position="dodge") +
scale_x_discrete(labels=c("Grammatical","Ungrammatical")) +
scale_y_continuous(formatter="percent", limits=c(0,1)) +
facet_grid(. ~ experiment) +
scale_fill_hue("Attractor", breaks=c("S","P"), labels=c("Singular","Plural"))
我尝试过 levels(df.all$number) = c("S", "P")
认为可能 ggplot 使用级别的顺序来决定绘图顺序,但这不起作用。我不确定还能尝试什么。有什么想法吗?
df.all
的内容,如果有用的话:
> df.all
number gram experiment V1
1 S G BERIMBAU_AGR_A 0.8133333
2 S G BERIMBAU_AGR_B 0.8658537
3 S U BERIMBAU_AGR_A 0.5436242
4 S U BERIMBAU_AGR_B 0.4597701
5 P G BERIMBAU_AGR_A 0.8580645
6 P G BERIMBAU_AGR_B 0.8536585
7 P U BERIMBAU_AGR_A 0.3087248
8 P U BERIMBAU_AGR_B 0.3975904
> str(df.all)
'data.frame': 8 obs. of 4 variables:
$ number : Factor w/ 2 levels "S","P": 2 2 2 2 1 1 1 1
..- attr(*, "scores")= num [1:2(1d)] 0 -1
.. ..- attr(*, "dimnames")=List of 1
.. .. ..$ : chr "P" "S"
$ gram : Factor w/ 2 levels "G","U": 1 1 2 2 1 1 2 2
$ experiment: Factor w/ 4 levels "BERIMBAU_AGR_A",..: 1 4 1 4 1 4 1 4
$ V1 : num 0.813 0.866 0.544 0.46 0.858 ...
【问题讨论】:
我认为这是 ggplot2 中的一个错误 - 它应该在躲避条时尊重数据顺序(或顺序美学),但我认为它可能不会。没有可重复的例子很难说。 哈德利,我可以给你一些数据和代码吗?我很擅长重现这个错误:) 【参考方案1】:我认为df.all$number
需要成为一个有序因素。试试df.all$number <- ordered(df.all$number)
【讨论】:
是的,然后您可以使用levels=c()
选项手动更改排序【参考方案2】:
在某些情况下,我认为这是不可能的:
layerCake<-data.frame(group=c(rep("normal",4),rep("tumor",4)),
class=factor(rep(c("exon","intron","intergenic","unmapped"),2),levels=rev(c("exon","intron","intergenic","unmapped")),ordered=TRUE),
fraction=c(.02,.25,.50,.23,.015,.20,.555,.23)
)
layerCake[layerCake$group=='normal',"reads"]<-130948403*layerCake[layerCake$group=='normal',"fraction"]
layerCake[layerCake$group=='tumor',"reads"]<-200948403*layerCake[layerCake$group=='tumor',"fraction"]
g<-ggplot(layerCake, aes(x=factor(group),y=reads, fill=factor(class),order = as.numeric(class)))+xlab("Group")+scale_fill_discrete(name="Anno Class",breaks=c("exon","intron","intergenic","unmapped"))
正确的堆叠顺序: g+geom_bar(stat="identity",position="stack")
闪避顺序不正确:
g+geom_bar(stat="identity",position="dodge")
让我们尝试颠倒ggplot中的顺序:
g<-ggplot(lc, aes(x=factor(group),y=reads, fill=factor(class),order = -as.numeric(class)))+xlab("Group")+scale_fill_discrete(name="Anno Class",breaks=c("exon","intron","intergenic","unmapped"))
g+geom_bar(stat="identity",position="dodge")
没有骰子
让我们尝试重新排序数据框
lc <- with(lc, lc[order(-as.numeric(class)), ])
g<-ggplot(lc, aes(x=factor(group),y=reads, fill=factor(class),order = -as.numeric(class)))+xlab("Group")+scale_fill_discrete(name="Anno Class",breaks=c("exon","intron","intergenic","unmapped"))
g+geom_bar(stat="identity",position="dodge")
没有
【讨论】:
【参考方案3】:Hadley 提供了解决方案。这是问题和解决方案的复制。
目标是让标有“S”的条出现在标有“P”的条之前。默认情况下不会发生这种情况,因为 R 按字母顺序排列级别。
df <- read.csv("http://pealco.net/code/ggplot_dodge/df.txt")
ggplot(df, aes(gram, V1, fill=number))
+ geom_bar(stat="identity", position="dodge")
正如 Hadley 在另一个答案中评论的那样,“您需要根据 x 变量而不是 y 变量重新排序”。虽然我不确定为什么会这样。
要翻转本例中因子的顺序,您可以将因子转换为数值并乘以 -1。
df <- with(df, df[order(gram, -as.numeric(number)), ])
我仍然想要更多关于df <- with(df, df[order(gram, -as.numeric(number)), ])
为何有效的解释。
【讨论】:
外部链接没有帮助。【参考方案4】:改变因子水平确实会改变躲避柱的顺序!常见陷阱:颜色仍然停留在某个位置,所以快速浏览会使看起来顺序没有改变。但是,如果您查看这些值,您会发现顺序确实发生了变化。
编辑:我之前的回答仅更改了条形图的配色顺序。这仍然很有用,因为我们可能经常希望在更改条形顺序的同时反转配色方案:
我使用 scale_fill_manual 是因为我想手动填充条形的颜色。
ggplot(data, aes_string(x = "countries", y = "population", fill = "agegroups")) +
scale_fill_manual(values = CustomColorFunction(), limits = (levels(data$agegroups)))
花了 5 个小时修补不断变化的因子水平并安排数据框,希望这对某人有所帮助!
【讨论】:
以上是关于更改 ggplot2 barplot 中闪避条的顺序的主要内容,如果未能解决你的问题,请参考以下文章
如何从 df 的不同列中获取闪避的 geom_bar (ggplot2)