Order of factor levels in facet_wrap

后端 未结 2 703
Happy的楠姐
Happy的楠姐 2020-12-21 11:22

I\'d like to produce a facet_wrap where the order of factors within facets is based on the one of the column factor order. The heart of the problem is each group has duplica

相关标签:
2条回答
  • 2020-12-21 11:46

    This solution makes each group unique and arranges in the desired order, then changes the names back to your original names.

    df_ex$names<-paste(df_ex$address,df_ex$clas,df_ex$No)
    df_ex$names<-factor(df_ex$names,levels=c("A Good 1","B Ugly 1","C Ugly 1", "A Good 2", "C Bad 2", "B Ugly 2", "C Good 3", "A Bad 3", "B Bad 3"))
    
    
    ggplot(df_ex, aes(x=names,y="",fill=clas)) + #x axis bias voltage dependence
      geom_tile() + 
      scale_fill_manual(values=c('Good'="green","Bad"="Blue","Ugly"="black"))+
      facet_wrap(~No,ncol=1,scales = "free_x")+
      theme(legend.position = "top",axis.text.y = element_text(size = 20,angle = 90),axis.text.x = element_text(size=12,face="bold",colour = "black"),
            axis.title.y = element_text(face="bold",size = 20, colour = "black"),
            axis.title.x = element_text(face="bold",size = 20 , colour = "black"),
            strip.text = element_text(size=26, face="bold"),
            strip.background = element_rect(fill="#FFFF66", colour="black", size=0.5),
            plot.title=element_text(face="bold",color="red",size=14),
            legend.title = element_text(colour="black", size=26,face="bold"),
            legend.text = element_text(colour="black", size=18))+
      labs(x = "address",y = "")+
      scale_x_discrete(breaks=df_ex$names, labels=df_ex$address)
    

    0 讨论(0)
  • 2020-12-21 11:55

    This old question has already an accepted answer. But as it is being used as a dupe target, I feel obliged to suggest a slightly improved and more concise variant.

    It's based on the recent enhancements of the ggplot2 package, namely the labels parameter to scale_x_discrete(), and Hadley's forcats package released to CRAN in August 2016. The proposed solution enhances the accepted answer by using material from this answer.

    Prepare data

    df_ex as provided by the OP needs to be modified to include a variable which guarantees an overall sort order across all facets:

    library(dplyr)   # version 0.5.0 used 
    df_ex <- df_ex %>% mutate(ordered = paste0(No, address) %>% 
                       forcats::fct_inorder())
    

    The additional column to df_ex now looks as follows:

      address    No   clas ordered
        <chr> <int> <fctr>  <fctr>
    1       A     1   Good      1A
    2       B     1   Ugly      1B
    3       C     1   Ugly      1C
    4       A     2   Good      2A
    5       C     2    Bad      2C
    6       B     2   Ugly      2B
    7       C     3   Good      3C
    8       A     3    Bad      3A
    9       B     3    Bad      3B
    

    As df_ex already had been sorted in the desired order using arrange(), fct_inorder() returns the new column ordered with the levels in the same order as their first appearance.

    Plotting

    Instead of address, ordered is plotted on the x-axis. The parameter scales = "free_x" to facet_wrap() ensures that unused levels will be dropped from the facets. However, the labels on the x-axis need to be be replaced by supplying a named vector to the labels parameter of scale_x_discrete().

    library(ggplot2)   # version 2.2.1 used
    ggplot(df_ex, aes(x=ordered,y="",fill=clas)) + #x axis bias voltage dependence
      geom_tile() + 
      scale_fill_manual(values=c('Good'="green","Bad"="Blue","Ugly"="black"))+
      facet_wrap(~No,ncol=1,scales = "free_x")+
      theme(legend.position = "top",axis.text.y = element_text(size = 20,angle = 90),axis.text.x = element_text(size=12,face="bold",colour = "black"),
            axis.title.y = element_text(face="bold",size = 20, colour = "black"),
            axis.title.x = element_text(face="bold",size = 20 , colour = "black"),
            strip.text = element_text(size=26, face="bold"),
            strip.background = element_rect(fill="#FFFF66", colour="black", size=0.5),
            plot.title=element_text(face="bold",color="red",size=14),
            legend.title = element_text(colour="black", size=26,face="bold"),
            legend.text = element_text(colour="black", size=18))+
      labs(x = "address",y = "") + 
      scale_x_discrete(labels = setNames(df_ex$address, df_ex$ord)) +
      
    

    0 讨论(0)
提交回复
热议问题