Woony
Woony

Reputation: 33

How to make different patterns and colors in different category of data using ggplot in R?

I would like to make my data have different colors for species and different patterns for sex. However, I can only set to make it different colors according to the sex. Here is my data, data

This is how I run my script,

#making bar plot
library(readr)
library(ggplot2)


# loading and checking the data
data_summary <- read_csv("trial.csv")
print(data_summary)


# coloured barplot
ggplot(data_summary, aes(x = factor(species), y = mean, fill = sex)) + 
  geom_bar(stat = "identity", position = "dodge", show.legend = FALSE)  +
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
  labs(x="", y="") + theme_bw() + 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
  theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
  scale_fill_manual(values=c("#870A30","#D3D3D3"))

Upvotes: 2

Views: 992

Answers (4)

Allan Cameron
Allan Cameron

Reputation: 173858

You can use ggpattern to get different patterns per sex and different colors per species:

library(ggplot2)
library(ggpattern)

ggplot(data_summary, aes(x = species, y = mean, fill = species, group = sex)) + 
  geom_col_pattern(position = "dodge", aes(pattern = sex), 
                   pattern_fill = "white", pattern_color = "white",
                   pattern_angle = 45, show.legend = FALSE)  +
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), 
                width = 0.2, show.legend = FALSE) +
  labs(x = NULL, y = NULL) + 
  theme_classic() + 
  theme(panel.border = element_rect(linewidth = 0.5, fill = NA)) + 
  ylim(0, 80) +
  scale_fill_manual(values = c("#870A30" ,"#D3D3D3"))

enter image description here

Upvotes: 2

MarBlo
MarBlo

Reputation: 4524

There is a nice package called ggpattern which offers hatching for geoms. Unfortunately it is not available for the R version I am using.

But I would like to offer different alpha values for the fill color.

The alpha itself can defined like scale_alpha_manual(values = c(.5,1)).

library(ggplot2)

data_summary <- read.table(text = "
  species,sex,mean,sd,tukey
  species_a,female,67,4.17,a
  species_b,male,62.2,4.8,a
  species_b,female,61.3,6.43,a
  species_a,male,49.7,16.2,a
", header = T, sep = ','
  
)


# coloured barplot
ggplot(data_summary, aes(x = factor(species), y = mean, fill = sex, alpha = species)) + 
  geom_bar(stat = "identity", position = "dodge", show.legend = FALSE)  +
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
  labs(x="", y="") + theme_bw() + 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
  theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
  scale_fill_manual(values=c("#870A30","#D3D3D3")) +
  scale_alpha_manual(values = c(.5,1))

Upvotes: 0

TarJae
TarJae

Reputation: 78927

This can be done using fill = interaction(..,..):

library(ggplot2)

ggplot(data_summary, aes(x = factor(species), y = mean, fill = interaction(species,sex))) +
  geom_bar(stat = "identity", position = "dodge", show.legend = FALSE) +
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
  labs(x="", y="") + 
  theme_bw() + 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
  theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
  scale_fill_manual(values= c("#870A30", '#009E73', '#CC79A7', "#D3D3D3"))

enter image description here

Upvotes: 1

Quinten
Quinten

Reputation: 41285

An option could be using ggplot_build and add a vector of four colors (you change this to what you want) to the fill column of the bars layer like this:

library(ggplot2)
p <- ggplot(data_summary, aes(x = factor(species), y = mean, fill = sex)) + 
  geom_bar(stat = "identity", position = "dodge", show.legend = FALSE)  +
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
  labs(x="", y="") + theme_bw() + 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
  theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
  scale_fill_manual(values=c("#870A30","#D3D3D3"))

q <- ggplot_build(p)

q$data[[1]]$fill <- c("#870A30","#D3D3D3", '#009E73', '#CC79A7')

q <- ggplot_gtable(q)

plot(q)

Created on 2023-01-02 with reprex v2.0.2

Upvotes: 1

Related Questions