Is there a way of manipulating ggplot scale breaks and labels?

前端 未结 2 615
北恋
北恋 2020-11-29 23:06

ggplot generally does a good job of creating sensible breaks and labels in scales.

However, I find that in plot with many facets and perhaps a for

2条回答
  •  一向
    一向 (楼主)
    2020-11-29 23:47

    The scales package contains several breaks_* and label_* functions which return functions (closures) that are used by ggplot. So, you can write a wrappers for these that modify the output.

    For example:

    library(ggplot2)
    
    # Compute the list of breaks using original_func,
    # then remove any of these that occur in remove_list
    remove_breaks <- function(original_func, remove_list = list()) {
      function(x) {
        original_result <- original_func(x)
        original_result[!(original_result %in% remove_list)]
      }
    }
    
    # Compute the list of labels using original_func,
    # then remove any of these that occur in remove_list
    remove_labels <- function(original_func, remove_list = list()) {
      function(x) {
        original_result <- original_func(x)
        replace(original_result, original_result %in% remove_list, '')
      }
    }
    
    # Original plot
    ggplot(data.frame(x=c(1,2,3,4,5,6,7,8), y = c(1,4,9,16,25,36,49,64))) + geom_line(aes(x, y)) +
      scale_x_continuous(breaks       = scales::breaks_pretty(9),
                         minor_breaks = scales::breaks_pretty(18),
                         labels       = scales::label_number_auto()) +
      scale_y_continuous(breaks       = scales::breaks_pretty(9),
                         minor_breaks = scales::breaks_pretty(18),
                         labels       = scales::label_number_auto())
    
    # Remove some breaks from the x-axis, and remove some labels from the y-axis
    ggplot(data.frame(x=c(1,2,3,4,5,6,7,8), y = c(1,4,9,16,25,36,49,64))) + geom_line(aes(x, y)) +
      scale_x_continuous(breaks       = remove_breaks(scales::breaks_pretty(9), seq(3,6)),
                         minor_breaks = remove_breaks(scales::breaks_pretty(18), seq(3,6,0.5)),
                         labels       = scales::label_number_auto()) +
      scale_y_continuous(breaks       = scales::breaks_pretty(9),
                         minor_breaks = scales::breaks_pretty(18),
                         labels       = remove_labels(scales::label_number_auto(), seq(20, 30)))
    

    Of course, with my simple remove_breaks and remove_labels functions you still have to specify which values to remove, but you can easily modify these to something that removes the max and min value, removes any value in a specified range, etc.

提交回复
热议问题