【问题标题】:Manually order x-axis labels within each facet in ggplot在ggplot中的每个方面手动排序x轴标签
【发布时间】:2023-04-08 05:39:02
【问题描述】:

我正在尝试手动重新排序每个方面内的 x 轴标签。

数据如下:

df = structure(list(block = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L), .Label = c("1", 
"2", "3", "4", "5"), class = "factor"), item = structure(c(14L, 
15L, 28L, 29L, 30L, 31L, 32L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 
15L, 22L, 23L, 24L, 25L, 26L, 27L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 
1L, 8L, 9L, 10L, 11L, 12L, 13L), .Label = c("p00e00d00", "p00e00d11", 
"p00e00d12", "p00e00d13", "p00e00d21", "p00e00d22", "p00e00d23", 
"p00e11d00", "p00e12d00", "p00e13d00", "p00e21d00", "p00e22d00", 
"p00e23d00", "p01e00d00", "p11e00d00", "p11e00d11", "p11e00d12", 
"p11e00d13", "p11e00d21", "p11e00d22", "p11e00d23", "p11e11d00", 
"p11e12d00", "p11e13d00", "p11e21d00", "p11e22d00", "p11e23d00", 
"p12e00d00", "p13e00d00", "p14e00d00", "p21e00d00", "p22e00d00"
), class = "factor"), response = structure(c(2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("2", 
"1"), class = "factor"), n = c(345L, 511L, 583L, 613L, 612L, 
222L, 142L, 531L, 546L, 589L, 636L, 478L, 364L, 313L, 502L, 533L, 
587L, 603L, 385L, 298L, 263L, 518L, 546L, 563L, 593L, 435L, 351L, 
310L, 478L, 579L, 629L, 646L, 357L, 307L, 230L), freq = c(0.408284023668639, 
0.604733727810651, 0.689940828402367, 0.725443786982249, 0.724260355029586, 
0.262721893491124, 0.168047337278107, 0.628402366863905, 0.646153846153846, 
0.697041420118343, 0.752662721893491, 0.565680473372781, 0.430769230769231, 
0.370414201183432, 0.594082840236686, 0.630769230769231, 0.694674556213018, 
0.713609467455621, 0.455621301775148, 0.352662721893491, 0.311242603550296, 
0.61301775147929, 0.646153846153846, 0.666272189349112, 0.701775147928994, 
0.514792899408284, 0.415384615384615, 0.366863905325444, 0.565680473372781, 
0.685207100591716, 0.744378698224852, 0.764497041420118, 0.422485207100592, 
0.363313609467456, 0.272189349112426)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -35L), .Names = c("block", "item", 
"response", "n", "freq"))

一共有五个方块,每个方块包含7个物品,有些物品在方块之间有相同的名称。因此,我可以按如下方式分块:

df %>% 
  ggplot(aes(x = item, y = freq)) + 
  geom_bar(stat = "identity", position = "dodge", color = "black") +
  facet_grid(.~block, scales = "free") + 
  coord_cartesian(ylim = c(0, 1), expand = F) +  # need to add expanse = F to prevent zooming away 
  scale_y_continuous(labels = scales::percent) +
  theme(axis.text.x = element_text(angle=45, hjust=1, vjust=1))

我也有向量,它为每个块说明项目应该出现的顺序。例如:

block_3_order = c("p11e13d00","p11e12d00", "p11e11d00", "p11e00d00", "p11e21d00", "p11e22d00","p11e23d00")
             )
block_4_order =  c("p00e00d13", "p00e00d12", "p00e00d11", "p00e00d00", "p00e00d21","p00e00d22","p00e00d23")
             )

我尝试重新排序“项目”因素,但为了获得预期的效果,我需要将数据帧拆分为代表块的子集。否则,我很难掌握如何将因素的排序与项目的 ggplot 处理集成为跨方面的单个因素。

非常感谢任何帮助。

【问题讨论】:

    标签: r ggplot2 dplyr


    【解决方案1】:

    要在每个分面中获得不同的自定义轴顺序,您可以将每个“分面”创建为单独的图,然后将它们放在一起,就像它们是单面图一样。

    library(tidyverse)
    #devtools::install_github("baptiste/egg")
    library(egg)
    library(gridExtra)
    library(grid)
    theme_set(theme_bw())
    

    首先,创建自定义排序。那些为 NULL 的将在最终图中按字母顺序排序。

    b.order = list(b1 = NULL,
                   b2 = NULL,
                   b3 = c("p11e13d00","p11e12d00", "p11e11d00", "p11e00d00", "p11e21d00", "p11e22d00","p11e23d00"),
                   b4 = c("p00e00d13", "p00e00d12", "p00e00d11", "p00e00d00", "p00e00d21","p00e00d22","p00e00d23"),
                   b5 = NULL)
    

    创建一个绘图列表,每个block 一个。我们通过将df 拆分为block 来做到这一点。为了获得自定义排序,我们使用factor根据列表b.order设置自定义排序。

    plist = map2(split(df, df$block), b.order,  
         ~ .x %>% group_by(block) %>% 
             mutate(item = factor(item, levels=if(is.null(.y)) sort(unique(item)) else .y)) %>%
           ggplot(aes(x = item, y = freq)) + 
            geom_bar(stat = "identity", position = "dodge", color = "black") +
            facet_grid(.~block, scales = "free") + 
            coord_cartesian(ylim = c(0, 1), expand = F) +  # need to add expanse = F to prevent zooming away 
            scale_y_continuous(labels = scales::percent) +
            theme(axis.text.x = element_text(angle=45, hjust=1, vjust=1),
                 plot.margin=margin(b=-5)) +
            labs(x=""))
    

    从除了最左边的所有图中删除 y 轴标签、标题和刻度:

    plist[2:length(plist)] = plist[2:length(plist)] %>% 
      map(~ .x + theme(axis.text.y=element_blank(),
                       axis.title.y=element_blank(),
                       axis.ticks.y=element_blank()))   
    

    安排情节。我们使用 egg 包中的 ggarrange 以确保绘图面板都具有相同的水平宽度。我们还需要在绘图下方添加Item 标签。然而,ggarrange 将绘图打印到输出设备,甚至在arrangeGrob 内部。所以我们创建对象p,清除设备,然后重新绘制最终的绘图。

    p = arrangeGrob(ggarrange(plots=plist, ncol=length(plist)),
                    textGrob("Item"), heights=c(20,1))
    grid.newpage()
    grid.draw(p)
    

    【讨论】:

    • 这是一个绝妙的答案,我非常感谢有关删除除最左边的轴和 ggarrange 之外的所有内容的提示。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 2019-08-25
    • 2017-07-26
    • 2019-04-03
    • 2014-07-02
    • 1970-01-01
    • 2013-12-29
    相关资源
    最近更新 更多