ggplot: Order bars in faceted bar chart per facet

后端 未结 4 1778
一向
一向 2020-11-30 10:32

I have a dataframe in R that I want to plot in a faceted ggplot bar chart.

I use this code in ggplot:

ggplot(data_long, aes(x = partei, y = wert, fil         


        
相关标签:
4条回答
  • 2020-11-30 10:40

    using the comments above I came up with this code:

    names <- levels(unique(data_long$kat))
    
    plist <- list()
    plist[]
    
    for (i in 1:length(names)) {
        d <- subset(data_long,kat == names[i])
        d$partei <- factor(d$partei, levels=d[order(d$wert),]$partei)
    
        p1 <- ggplot(d, aes(x = partei, y = wert, fill = kat, width=0.75)) + 
        labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
        geom_bar(stat = "identity") +
        facet_wrap(~kat) +
        scale_y_continuous(limits=c(0, 100)) +
        coord_flip() +
        guides(fill=FALSE) +
        theme_bw() + theme( strip.background  = element_blank(),
                            panel.grid.major = element_line(colour = "grey80"),
                            panel.border = element_blank(),
                            axis.ticks = element_line(size = 0),
                            panel.grid.minor.y = element_blank(),
                            panel.grid.major.y = element_blank() ) +
        theme(legend.position="bottom") +
        scale_fill_brewer(palette="Set2")
    
    
        plist[[names[i]]] = p1
    }   
    
    
    
    do.call("grid.arrange", c(plist, ncol=4)
    

    not as elegant though... but it gives this:

    all nicely ordered descending :-)

    0 讨论(0)
  • 2020-11-30 10:50

    No need of additionale packages, you can achieve this with plain ggplot:

    1. create an additionale variable for every row
    2. make it a factor, reorder the levels
    3. change the lables of the plot to the original value

    The complete solution:

    data_long %>% 
      mutate(kat_partei = paste0(kat, '_', partei),
             kat_partei = forcats::fct_reorder(kat_partei, wert)) %>% 
      ggplot(aes(x = kat_partei, y = wert, fill = kat, width=0.75)) + 
      geom_bar(stat = "identity", show.legend = FALSE) +
      scale_x_discrete(name=NULL, labels=function(x) sub('^.*_(.*)$', '\\1', x)) +
      scale_fill_brewer(palette="Set2") +
      coord_flip() +
      facet_wrap(~kat, scales='free_y') +
      labs(y = "Wähleranteil [ % ]") +
      theme_bw() + theme(strip.background  = element_blank(),
                         panel.grid.major = element_line(colour = "grey80"),
                         panel.border = element_blank(),
                         axis.ticks = element_line(size = 0),
                         panel.grid.minor.y = element_blank(),
                         panel.grid.major.y = element_blank())
    

    further hints:

    • use geom_col() instead of geom_bar(stat = "identity")
    • use show.legend argument instead of guides(fill=FALSE)
    0 讨论(0)
  • 2020-11-30 10:55

    Because it's sometimes easier to see all code in action, here's a solution for you that generates all plots inside one call to lapply. There were some other issues to figure out (ordering, getting the colors right) and I like a puzzle.

    #create list of plots
    myplots <- lapply(split(dat,dat$kat), function(x){
      #relevel factor partei by wert inside this subset
      x$partei <- factor(x$partei, levels=x$partei[order(x$wert,decreasing=F)])
    
      #make the plot
      p <- ggplot(x, aes(x = partei, y = wert, fill = kat, width=0.75)) +
        geom_bar(stat = "identity") +
        scale_fill_discrete(drop=F)+ #to force all levels to be considered, and thus different colors
        theme_bw()+
        theme(legend.position="none")+
        labs(y="Wähleranteil (%)", x="", title=unique(x$kat))+
        coord_flip()
    })
    
    library(gridExtra)
    
    do.call(grid.arrange,(c(myplots, ncol=3)))
    

    0 讨论(0)
  • 2020-11-30 10:56

    The easiest solution would be to use the bar_chart() function from the ggcharts package. Note that unlike in the answer of @Heroka all subplot have a common x axis.

    chart <- ggcharts::bar_chart(
      data_long,
      partei,
      wert,
      fill = kat,
      facet = kat
    )
    chart
    

    The result of bar_chart() is an object of type ggplot so you can apply any ggplot2 function to it.

    chart +
      labs(y = "Wähleranteil [ % ]", x = NULL, fill = NULL) +
      theme_bw() +
      theme(
        strip.background  = element_blank(),
        panel.grid.major = element_line(colour = "grey80"),
        panel.border = element_blank(),
        axis.ticks = element_line(size = 0),
        panel.grid.minor.y = element_blank(),
        panel.grid.major.y = element_blank(),
        legend.position = "none"
      ) +
      scale_fill_brewer(palette = "Set2")
    

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