Overlaying boxplot with histogram in ggplot2

后端 未结 3 527
花落未央
花落未央 2021-01-13 17:33

Hi I want to create a similar chart as shown below with R script:

taken from: https://community.tableau.com/thread/194440

this is my code in R :

相关标签:
3条回答
  • 2021-01-13 18:13

    A good example where ggstance package comes in handy.

    library(ggplot2)
    library(ggstance)
    
    ggplot(iris, aes(x = Sepal.Length)) +
      geom_histogram() +
      geom_boxploth(aes(y = 3), width = 2, color = "blue", lwd = 2, alpha = .5) +
      theme_minimal() +
      facet_wrap(~Species, ncol = 1)
    

    0 讨论(0)
  • 2021-01-13 18:16

    You can try to replace histogram with rectangles to generate a plot like this:


    How to do this:

    Generate random data

    df <- data.frame(State = LETTERS[1:3],
                     Y = sample(1:10, 30, replace = TRUE),
                     X = rep(1:10, 3))
    

    Replace histogram with rectangles

    library(ggplot2)
    
    # You can plot geom_histogram or bar (pre-counted stats)
    ggplot(df, aes(X, Y)) +
        geom_bar(stat = "identity", position = "dodge") +
        facet_grid(State ~ .)
    # Or you can plot similar figure with geom_rect
    ggplot(df)  +
        geom_rect(aes(xmin = X - 0.4, xmax = X + 0.4, ymin = 0, ymax = Y)) +
        facet_grid(State ~ .)
    

    Add boxplot

    To add boxplot we need to:

    1. Flip coordinates (function coord_flip)
    2. Switch X and Y values in geom_rect

    Code:

    ggplot(df)  +
        geom_rect(aes(xmin = 0, xmax = Y, ymin = X - 0.4, ymax = X + 0.4)) +
        geom_boxplot(aes(X, Y)) +
        coord_flip() +
        facet_grid(State ~ .)
    

    Result:

    Final plot code with nicer visuals

    ggplot(df)  +
        geom_rect(aes(xmin = 0, xmax = Y, ymin = X - 0.4, ymax = X + 0.4),
                  fill = "blue", color = "black") +
        geom_boxplot(aes(X, Y), alpha = 0.7, fill = "salmon2") +
        coord_flip() +
        facet_grid(State ~ .) +
        theme_classic() +
        scale_y_continuous(breaks = 1:max(df$X))
    
    0 讨论(0)
  • 2021-01-13 18:20

    You're getting Error: stat_bin() must not be used with a y aesthetic. because you can't specify y in the aesthetic of a histogram. If you want to mix plots that have different parameters, you need to supply distinct aesthetics. I'll demonstrate with iris like so:

    ggplot(iris, aes(x = Sepal.Width)) + 
      geom_histogram(binwidth = 0.05) +
      geom_boxplot(aes(x = 3, y = Sepal.Width))
    

    Unfortunately, the default for boxplots is vertical, for histograms is horizontal, and coord_flip() is all-or-nothing, so you're left with this awful thing:

    Best I can figure out is instead of having them overlap, put one on top of the other with the gridExtra package:

    a <- ggplot(iris, aes(x = Sepal.Width)) + 
      geom_histogram(binwidth = 0.05) 
    
    b <- ggplot(iris, aes(x = "", y = Sepal.Width)) + 
      geom_boxplot() + 
      coord_flip()
    
    grid.arrange(a,b,nrow=2)
    

    which gives us something pretty good:

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