Two horizontal bar charts with shared axis in ggplot2 (similar to population pyramid)

前端 未结 1 596
隐瞒了意图╮
隐瞒了意图╮ 2020-12-02 23:58

I want to plot two variables on one plot similar to a population pyramid similar to this:

相关标签:
1条回答
  • 2020-12-03 00:17

    Here is very long workaround for your plot. Idea is to create new plot that contains only state names and ticks on both sides and then use this as the middle plot.

    For this plot I added title with no name to get space and ylab(NULL) to remove space. For left and right margin values are -1 to get plot closer to other plots. Library grid should be added before plotting to use function unit() for plot margins.

    library(grid)
    g.mid<-ggplot(DATA,aes(x=1,y=state))+geom_text(aes(label=state))+
      geom_segment(aes(x=0.94,xend=0.96,yend=state))+
      geom_segment(aes(x=1.04,xend=1.065,yend=state))+
      ggtitle("")+
      ylab(NULL)+
      scale_x_continuous(expand=c(0,0),limits=c(0.94,1.065))+
      theme(axis.title=element_blank(),
            panel.grid=element_blank(),
            axis.text.y=element_blank(),
            axis.ticks.y=element_blank(),
            panel.background=element_blank(),
            axis.text.x=element_text(color=NA),
            axis.ticks.x=element_line(color=NA),
            plot.margin = unit(c(1,-1,1,-1), "mm"))
    

    Both original plots are modified. First, removed the y axis for the second plot and also made left/right margin to -1.

    g1 <- ggplot(data = DATA, aes(x = state, y = sales_staff)) +
      geom_bar(stat = "identity") + ggtitle("Number of sales staff") +
      theme(axis.title.x = element_blank(), 
            axis.title.y = element_blank(), 
            axis.text.y = element_blank(), 
            axis.ticks.y = element_blank(), 
            plot.margin = unit(c(1,-1,1,0), "mm")) +
      scale_y_reverse() + coord_flip()
    
    g2 <- ggplot(data = DATA, aes(x = state, y = sales)) +xlab(NULL)+
      geom_bar(stat = "identity") + ggtitle("Sales (x $1000)") +
      theme(axis.title.x = element_blank(), axis.title.y = element_blank(), 
            axis.text.y = element_blank(), axis.ticks.y = element_blank(),
            plot.margin = unit(c(1,0,1,-1), "mm")) +
      coord_flip()
    

    Now use library gridExtra and function d grid.arrange() to join plots. Before plotting all plots are made as grobs.

    library(gridExtra)
    gg1 <- ggplot_gtable(ggplot_build(g1))
    gg2 <- ggplot_gtable(ggplot_build(g2))
    gg.mid <- ggplot_gtable(ggplot_build(g.mid))
    
    grid.arrange(gg1,gg.mid,gg2,ncol=3,widths=c(4/9,1/9,4/9))
    

    enter image description here

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