Left justify text from multi-line facet labels

后端 未结 3 1335
温柔的废话
温柔的废话 2021-01-03 22:57

I\'m using facet_grid() to display some data, and I have facet labels that span multiple lines of text (they contain the "\\n" character).

require(g         


        
相关标签:
3条回答
  • 2021-01-03 23:15

    There may be a cleaner way to do this but I didn't find a way to do this within ggplot2. The padwrap function could be more generalized as it basically does just what you requested. To get the justification right, I had to use a mono-spaced font.

    # Wrap text with embedded newlines: space padded and lef justified.
    # There may be a cleaner way to do this but this works on the one
    # example.  If using for ggplot2 plots, make the font `family`
    # a monospaced font (e.g. 'Courier')
    padwrap <- function(x) {
        # Operates on one string
        padwrap_str <- function(s) {
            sres    <- strsplit(s, "\n")
            max_len <- max(nchar(sres[[1]]))
            paste( sprintf(paste0('%-', max_len, 's'), sres[[1]]), collapse = "\n" )
        }
        # Applys 'padwrap' to a vector of strings
        unlist(lapply(x, padwrap_str))
    }
    
    require(ggplot2)
    
    facet_label_text = rep(c("Label A",
                             "Label B\nvery long label",
                             "Label C\nshort",
                             "Label D"), 5)
    new_facet_label_text <- padwrap(facet_label_text)
    
    #Generate example data
    set.seed(3)
    df = data.frame(facet_label_text = new_facet_label_text,
                    time = rep(c(0, 4, 8, 12, 16), times = 4),
                    value = runif(20, min=0, max=100))
    
    #Plot test data
    ggplot(df, aes(x = time, y = value)) +
        geom_line() +
        facet_grid(facet_label_text ~ .) +
        theme(strip.text.y = element_text(angle = 0, hjust = 0, family = 'Courier'))
    

    The strip text is left justified in the image below

    0 讨论(0)
  • 2021-01-03 23:30

    This is fairly straightforward using grid's grid.gedit function to edit the strips.

    library(ggplot2)  # v2.1.0
    library(grid)
    
    # Your data
    set.seed(3)
    df = data.frame(facet_label_text = rep(c("Label A",
                                             "Label B\nvery long label",
                                             "Label C\nshort",
                                             "Label D"), 
                                           each = 5),
                    time = rep(c(0, 4, 8, 12, 16), times = 4),
                    value = runif(20, min=0, max=100))
    
    # Your plot
    p = ggplot(df, aes(x = time, y = value)) +
        geom_line() +
        facet_grid(facet_label_text ~ .) +
        theme(strip.text.y = element_text(angle = 0, hjust = 0))
    p
    
    # Get a list of grobs in the plot
    grid.ls(grid.force())  
    
    # It looks like we need the GRID.text grobs.
    # But some care is needed:
    # There are GRID.text grobs that are children of the strips;
    # but also there are GRID.text grobs that are children of the axes.
    # Therefore, a gPath should be set up 
    # to get to the GRID.text grobs in the strips
    
    # The edit
    grid.gedit(gPath("GRID.stripGrob", "GRID.text"),  
             just = "left", x = unit(0, "npc"))
    

    Or, a few more lines of code to work with a grob object (in place of editing on screen as above):

    # Get the ggplot grob
    gp = ggplotGrob(p)
    grid.ls(grid.force(gp))
    
    # Edit the grob
    gp = editGrob(grid.force(gp), gPath("GRID.stripGrob", "GRID.text"), grep = TRUE, global = TRUE,
              just = "left", x = unit(0, "npc"))
    
    # Draw it
    grid.newpage()
    grid.draw(gp)
    

    0 讨论(0)
  • 2021-01-03 23:32

    Until someone comes along with a real solution, here's a hack: Add space in the labels to get the justification you want.

    require(ggplot2)
    
    #Generate example data
    set.seed(3)
    df = data.frame(facet_label_text = rep(c("Label A",
                                             "Label B           \nvery long label",
                                             "Label C\nshort     ",
                                             "Label D"),
                                           each = 5),
                    time = rep(c(0, 4, 8, 12, 16), times = 4),
                    value = runif(20, min=0, max=100))
    
    #Plot test data
    ggplot(df, aes(x = time, y = value)) +
      geom_line() +
      facet_grid(facet_label_text ~ .) +
      theme(strip.text.y = element_text(angle = 0, hjust = 0))
    

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