5

Based on the ggplot2 package, I want to add different textures to different bars of a barplot. Furthermore, I want to add these textures to the legend of the barplot.

Consider the following reproducible example:

# Create example data
data_ggp <- data.frame(category = rep(c("cat1", "cat2", "cat3"), 4),
                       values = c(0.664, 0.045, 0.291, 0.482, 0.029, 0.489, 0.537, 0.027, 0.436, 0.536, 0.028, 0.436),
                       group = c(rep("group1a", 3), rep("group1b", 3), rep("group2a", 3), rep("group2b", 3)))

# Load ggplot2
library("ggplot2")

# Draw barchart (not overlayed)
ggplot(data_ggp, aes(category, values)) + 
  geom_bar(stat = "identity", aes(fill = group), position = "dodge") +
  scale_fill_manual(" ", 
                    labels = c("group1a", "group1b", "group2a", "group2b"),
                    values = c("group1a" = "deepskyblue4", "group1b" = "darkolivegreen4", 
                               "group2a" = "deepskyblue1", "group2b" = "darkolivegreen2"))

enter image description here

To this barplot, I would like to draw diagonal lines to group 2a and vertical + horizontal lines to group 2b. The legend should contain these textures, too.

The final barplot should look as follows (drawn in paint):

enter image description here

I found a relatively old thread on stack overflow: How to add texture to fill colors in ggplot2?

Unfortunately, this code is very complex, not automatized, and difficult to apply to different types of barplots. Furthermore, I would like to add the textures to my legend.

Question: How to add different textures to different bars of a barplot + to the legend of the barplot?

Joachim Schork
  • 2,025
  • 3
  • 25
  • 48
  • Check Hadley's answer in the linked post. It appears there's no update yet. Therefore, your best bet is on that function however complex it is. Perhaps try to refactor it? – NelsonGon Jan 08 '19 at 13:59
  • Maybe this? https://cran.r-project.org/web/packages/patternplot/patternplot.pdf – NelsonGon Jan 08 '19 at 14:00
  • @NelsonGon Have you seen that I am mentioning this thread in my question? The other thread has a very unautomized code and it also is not showing how to add texture to a legend. The answer of Check Hadley is from 2010, so there might have been an update since then. – Joachim Schork Jan 08 '19 at 14:01
  • Check my comment on Hadley's answer? That was last year. There's no update. I thought of this myself late last year. – NelsonGon Jan 08 '19 at 14:02
  • I saw your comment from last year, but since he didn't reply I am still wondering if there might be an update. Thank you for the link to the package, did you have success with the package? – Joachim Schork Jan 08 '19 at 14:06
  • Running the examples in the package produces some textured bars. – NelsonGon Jan 08 '19 at 14:11
  • 1
    @IanCampbell Thank you so much for showing me this. In fact, I was so impressed by the ggpattern package that I have created a tutorial about the package on my website. In case you are interested, you may check it out here: https://statisticsglobe.com/ggpattern-r-package – Joachim Schork Nov 26 '20 at 16:49

1 Answers1

1

I was able to solve this using ggpattern

# remotes::install_github("coolbutuseless/ggpattern")
library(ggpattern)
library(ggplot2)

data_ggp <- data.frame(category = rep(c("cat1", "cat2", "cat3"), 4),
                       values = c(0.664, 0.045, 0.291, 0.482, 0.029, 0.489, 0.537, 0.027, 0.436, 0.536, 0.028, 0.436),
                       group = c(rep("group1a", 3), rep("group1b", 3), rep("group2a", 3), rep("group2b", 3)))

ggplot(data_ggp, aes(category, values)) + 
  geom_bar_pattern(stat = "identity", 
                   pattern = c("none", "none", "none", # 1st col
                               "none", "none", "none", # 2nd col
                               "stripe", "stripe", "stripe", # 3rd col
                               "crosshatch", "crosshatch", "crosshatch" # 4th col 
                               ),
                   pattern_angle = c(rep(0, 6), rep(45, 3), rep(0, 3)),
                   pattern_density = .1,
                   pattern_spacing = .04,
                   pattern_fill = 'black',
                   aes(fill = group), 
                   position = "dodge") +
  scale_fill_manual(" ", 
                    labels = c("group1a", "group1b", "group2a", "group2b"),
                    values = c("group1a" = "deepskyblue4", "group1b" = "darkolivegreen4", 
                               "group2a" = "deepskyblue1", "group2b" = "darkolivegreen2")) +
  guides(fill = guide_legend(override.aes = 
                               list(
                                 pattern = c("none", "none", "stripe", "crosshatch"),
                                 pattern_spacing = .01,
                                 pattern_angle = c(0, 0, 45, 0)
                                 )
                             ))

Created on 2021-01-13 by the reprex package (v0.3.0)

John-Henry
  • 1,556
  • 8
  • 20