修复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) 绘制上述数据的条形图。当我使用以下代码时,我没有按照数据中显示的顺序获取变量 typesize。请看图。为此,我使用了以下代码。

 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中构面的顺序的主要内容,如果未能解决你的问题,请参考以下文章

更改 ggplot2 barplot 中闪避条的顺序

ggplot 条形图,具有与方面相关的类别顺序

plotly 和 ggplot 图例顺序交互

为啥使用 ggplotly 时我的工具提示的顺序会发生变化?

使用 ggplot2 库的热图上的变量顺序 [重复]

ggplot图例:更改自动图例的顺序