Using ggplot2, can I insert a break in the axis?

后端 未结 7 2055
我寻月下人不归
我寻月下人不归 2020-11-22 03:27

I want to make a bar plot where one of the values is much bigger than all other values. Is there a way of having a discontinuous y-axis? My data is as follows:



        
7条回答
  •  说谎
    说谎 (楼主)
    2020-11-22 03:56

    Eight years later, the ggforce package offers a facet_zoom() extension which is an implementation of Hadley Wickham's suggestion to show two plots (as referenced in Brian Diggs' answer).

    Zoom facet

    library(ggforce)
    ggplot(df) + 
      aes(x = b, y = a) +
      geom_col() +
      facet_zoom(ylim = c(0, 10))
    

    Unfortunately, the current version 0.2.2 of ggforce throws an error with coord_flip() so only vertical bars can be shown.

    The zoomed facet shows the variations of the small values but still contains the large - now cropped - a4 bar. The zoom.data parameter controls which values appear in the zoomed facet:

    library(ggforce)
    ggplot(df) + 
      aes(x = b, y = a) +
      geom_col() +
      facet_zoom(ylim = c(0, 10), zoom.data = ifelse(a <= 10, NA, FALSE))
    

    Two plots

    Hadley Wickham suggested

    I think it's much more appropriate to show two plots - one of all the data, and one of just the small values.

    This code creates two plots

    library(ggplot2)
    g1 <- ggplot(df) + 
      aes(x = b, y = a) +
      geom_col() +
      coord_flip()
    g2 <- ggplot(df) + 
      aes(x = b, y = a) +
      geom_col() +
      coord_flip() +
      ylim(NA, 10)
    

    which can be combined into one plot by

    cowplot::plot_grid(g1, g2) # or ggpubr::ggarrange(g1, g2)
    

    or

    gridExtra::grid.arrange(g1, g2) # or egg::ggarrange(g1, g2)
    

    Two facets

    This was suggested in a comment by Chase and also by Brian Diggs in his answer who interpreted Hadley's suggestion to use

    faceted plots, one with all the data, one zoomed in a particular region

    but no code was supplied for this approach, so far.

    As there is no simple way to scale facets separately (see related question, e.g.) the data needs to be manipulated:

    library(dplyr)
    library(ggplot2)
    ggplot() + 
      aes(x = b, y = a) +
      geom_col(data = df %>% mutate(subset = "all")) +
      geom_col(data = df %>% filter(a <= 10) %>% mutate(subset = "small")) +
      coord_flip() + 
      facet_wrap(~ subset, scales = "free_x")
    

提交回复
热议问题