修复ggplot中构面的顺序
Posted
技术标签:
【中文标题】修复ggplot中构面的顺序【英文标题】:Fixing the order of facets in ggplot 【发布时间】:2012-12-25 02:39:03 【问题描述】:数据:
df <- data.frame(
type = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"),
size = c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"),
amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)
我需要使用 ggplot (x-axis -> type
, y-axis -> amount
, group by size
) 绘制上述数据的条形图。当我使用以下代码时,我没有按照数据中显示的顺序获取变量 type
和 size
。请看图。为此,我使用了以下代码。
ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) +
geom_col(width=0.5, position = position_dodge(width=0.6)) +
facet_grid(.~size) +
theme_bw() +
scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"),
labels = c("T", "F", "P"))
.
为了解决订单问题,我使用以下方法对变量“type”使用了因子方法。也请看图。
temp$new = factor(temp$type, levels=c("T","F","P"), labels=c("T","F","P"))
但是,现在我不知道如何修复变量size
的顺序。它应该是 50%、100%。 150% 和 200%。
【问题讨论】:
【参考方案1】:通过以下方式使您的尺寸成为数据框中的一个因素:
temp$size_f = factor(temp$size, levels=c('50%','100%','150%','200%'))
然后把facet_grid(.~size)
改成facet_grid(.~size_f)
然后绘制:
现在图表的顺序正确。
【讨论】:
【参考方案2】:这里有几个很好的解决方案。
与 Harpal 的回答类似,但在方面,因此 不需要对基础数据或预绘图操作进行任何更改:
# Change this code:
facet_grid(.~size) +
# To this code:
facet_grid(~factor(size, levels=c('50%','100%','150%','200%')))
这是灵活的,并且可以在您更改分面元素时针对任何变量实施,无需对数据进行基本更改。
【讨论】:
levels 是 facet_grid 的秘密输入? 它对我不起作用(R4.0.3,ggplot2 3.3.3)。 @elarry 我已经编辑了应该适合你的代码。告诉我。 那么在这种情况下,如何通过labeller
更换条形贴标机?
@just_rookie,我没有这样做,但稍微探索了一下,我成功了:“facet_grid(~factor(size, levels = c('50%', '100%' , '150%', '200%'), labels = c('50%' = "五十", '100%' = "一百", '150%' = "五十", '200%' = “两百”)))【参考方案3】:
甚至更少的操纵:
facet_grid(~fct_relevel(size,'50%','100%','150%','200%'))
【讨论】:
很好的答案!可能值得注意的函数来自 forcats 包:forcats::fct_relevel
【参考方案4】:
这是一个将事物保存在 dplyr 管道链中的解决方案。您提前对数据进行排序,然后使用 mutate_at 转换为因子。我稍微修改了数据,以展示如何普遍应用此解决方案,给定可以合理排序的数据:
# the data
temp <- data.frame(type=rep(c("T", "F", "P"), 4),
size=rep(c("50%", "100%", "200%", "150%"), each=3), # cannot sort this
size_num = rep(c(.5, 1, 2, 1.5), each=3), # can sort this
amount=c(48.4, 48.1, 46.8,
25.9, 26.0, 24.9,
20.8, 21.5, 16.5,
21.1, 21.4, 20.1))
temp %>%
arrange(size_num) %>% # sort
mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>% # convert to factor
ggplot() +
geom_bar(aes(x = type, y=amount, fill=type),
position="dodge", stat="identity") +
facet_grid(~ size)
您也可以应用此解决方案来排列构面内的条形,但您只能选择一个首选顺序:
temp %>%
arrange(size_num) %>%
mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>%
arrange(desc(amount)) %>%
mutate_at(vars(type), funs(factor(., levels=unique(.)))) %>%
ggplot() +
geom_bar(aes(x = type, y=amount, fill=type),
position="dodge", stat="identity") +
facet_grid(~ size)
ggplot() +
geom_bar(aes(x = type, y=amount, fill=type),
position="dodge", stat="identity") +
facet_grid(~ size)
【讨论】:
在 dplyr 1.0 中,更新方法将结合 mutate() 和 cross()【参考方案5】:与 glenn_in_boston 的回答类似,但在关卡中没有硬编码。
# Change this code:
facet_grid(.~size) +
# To this code:
facet_grid(~factor(size, levels=unique(df$size)))
之所以有效,是因为数据框中的大小是从最小到最大排列的。
如果尺寸已经是一个因素,并且您只想在绘图时翻转顺序,这是一个选项:
# Updating dataframe so size is a factor ordered smallest to largest
df <- data.frame(
type = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"),
size = factor(c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"), levels=c("50%", "100%","150%","200%"), ordered = TRUE),
amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)
# Now plotting with facets in the reverse order
ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) +
geom_col(width=0.5, position = position_dodge(width=0.6)) +
facet_grid(~factor(size, levels=rev(unique(df$size)))) + #this part updated
theme_bw() +
scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"),
labels = c("T", "F", "P"))
【讨论】:
以上是关于修复ggplot中构面的顺序的主要内容,如果未能解决你的问题,请参考以下文章