rggplot2bar-chartlegend

How to create a bar graph to visually represent two variables, while keeping the same color for the x-axis variable?


For example, here is a data.

Genotype=c("A","A","B","B","C","C","A","A","B","B","C","C")
Season=c("2022","2023","2022","2023","2022","2023","2022","2023","2022","2023","2022","2023")
Type=c("I","I","I","I","I","I","II","II","II","II","II","II")
Yield=c(100,120,110,80,60,90,100,100,170,80,30,90)
dataA= data.frame(Genotype, Season, Type, Yield)

And I created a bar graph

ggplot(data=dataA, aes(x=Genotype, y=Yield, fill=Genotype, group1=Season, color=Season))+
  geom_bar(stat="identity",position="dodge", width= 0.7, size=1) +
  scale_fill_manual(values=c("darkred","blue","grey")) +
  scale_color_manual(values=c("black","orange")) +
  labs(x="Genotype", y="Yield") +
  theme_classic(base_size=18, base_family="serif") +
  theme(legend.position="right",
        legend.title=element_blank(),
        legend.key=element_rect(color="white", fill="white"),
        legend.text=element_text(family="serif", face="plain",
                                 size=15, color="black"),
        legend.background= element_rect(fill="white"),
        axis.line = element_line(linewidth = 0.5, colour="black"))+
windows(width=7, height=5)

enter image description here

However, my intention is to display only the legend for the season. Within each genotype, I aim to maintain consistent colors while differentiating the two bars, perhaps using lines, dashes, or other visual distinctions. For example, like below, or other way to distinguish two bars between two seasons.

enter image description here

Could you tell me how to do that?


Solution

  • Using ggpattern, you can do:

    library(tidyverse)
    library(ggpattern)
    
    dataA %>%
      group_by(Season, Genotype) %>%
      summarise(Yield = sum(Yield), .groups = "drop") %>%
      ggplot(aes(Genotype, Yield, fill = Genotype, pattern = Season,
                 pattern_type = Season)) +
      geom_col_pattern(position = "dodge", pattern_fill = "black", color = "black",
                       pattern_angle = 45, pattern_spacing = 0.02,
                       pattern_color = "black") +
      scale_pattern_type_manual(NULL, values = c("none", "stripe")) +
      scale_pattern_manual(NULL, values = c("none", "stripe")) +
      scale_fill_manual(values = c("darkred", "blue", "grey"), guide = "none") +
      theme_classic(base_size=18, base_family="serif") +
      theme(legend.key = element_rect(color = "white", fill = "white"),
            legend.text = element_text(color = "black"),
            axis.line = element_line(linewidth = 0.5, colour = "black"))
    

    enter image description here

    Note that it's not clear how you want to deal with the Type variable. Presumably, since this is not referenced on your initial plot, you want the two types stacked, which I have done here by summing them prior to plotting.