kitkat23
kitkat23

Reputation: 35

Adding manual p-values to grouped bargraph in ggplot2

I am trying to add a manual p-value to my grouped bargraph on ggplot2. I have tried the geom_sigf function suggested in previous posts (with manual coordinates) but there is no output on my graph. I would like to add "<0.001" for the three comparisons across the graph.

data <- data.frame(group = c("A", "B","A", "B","A", "B"),
               variable = c("X", "X", "Y", "Y", "Z", "Z"),
               value = c(10, 40, 1, 15, 10, 25))

ggplot(data = data, aes(fill=group, x=variable, y=value)) +
 geom_bar(position="dodge", stat = "identity") +
 geom_text(aes(label=value), position=position_dodge(width=0.9), vjust=-0.2, size = 5) +
 labs(x = "") +
 labs(y="Proportion (%)") +
 theme(legend.title = element_blank(), legend.position = "bottom") +
 theme(axis.text.x = element_text(size=12, color = "black")) +
 theme(axis.text.y = element_text(size = 12)) +
 theme(legend.text = element_text(size = 12)) +
 theme(axis.title.y = element_text(size = 12)) +
 scale_y_continuous(limits = c(0,60)) 

enter image description here`

Much appreciated!

Upvotes: 1

Views: 1943

Answers (3)

kitkat23
kitkat23

Reputation: 35

data <- data.frame(group = c("A", "B","A", "B","A", "B"),
variable = c("X", "X", "Y", "Y", "Z", "Z"),
value = c(10, 40, 1, 15, 10, 25))

ggplot(data = data, aes(fill=group, x=variable, y=value)) +
geom_bar(position="dodge", stat = "identity") +
geom_text(aes(label=value), 
position=position_dodge(width=0.9), vjust=-0.2, size = 5) +
labs(x = "") +
labs(y="Proportion (%)") +
theme(legend.title = element_blank(), legend.position = 
"bottom") +
theme(axis.text.x = element_text(size=12, color = 
"black")) +
theme(axis.text.y = element_text(size = 12)) +
theme(legend.text = element_text(size = 12)) +
theme(axis.title.y = element_text(size = 12)) +
scale_y_continuous(limits = c(0,60)) +
annotate("rect", xmin = 0.75, xmax = 1.25, ymin = 50, ymax 
=50, alpha = 1, color = "black") +
annotate("rect", xmin = 0.75, xmax = 0.75, ymin = 49, ymax 
=50.09, alpha=1, colour = "black") +
annotate("rect", xmin = 1.25, xmax = 1.25, ymin = 49, ymax 
=50.09, alpha=1, colour = "black")+       
annotate("rect", xmin = 1.75, xmax = 2.25, ymin = 25, ymax 
=25, alpha = 1, color = "black") +
annotate("rect", xmin = 1.75, xmax = 1.75, ymin = 24, ymax 
=25.09, alpha=1, colour = "black") +
annotate("rect", xmin = 2.25, xmax = 2.25, ymin = 24, ymax 
=25.09, alpha=1, colour = "black") +
annotate("rect", xmin = 2.75, xmax = 3.25, ymin = 36, ymax 
=36, alpha = 1, color = "black") +
annotate("rect", xmin = 2.75, xmax = 2.75, ymin = 35, ymax 
=36.09, alpha=1, colour = "black") +
annotate("rect", xmin = 3.25, xmax = 3.25, ymin = 35, ymax 
=36.09, alpha=1, colour = "black") +
annotate(geom = "text", x = 1.0, y = 52, label = "p 
<0.01", 
color = "black") +
annotate(geom = "text", x = 2.0, y = 27, label = "p 
<0.01", 
color = "black") +
annotate(geom = "text", x = 3.0, y = 38, label = "p 
<0.01", 
color = "black") 

Not elegant at all but was able to annotate horizontal and vertical lines to create the brackets and add p-values. Will have to try out ggbracket next time.

Upvotes: 0

ViviG
ViviG

Reputation: 1726

You can use annotate:

data <- data.frame(group = c("A", "B","A", "B","A", "B"),
                   variable = c("X", "X", "Y", "Y", "Z", "Z"),
                   value = c(10, 40, 1, 15, 10, 25))

ggplot(data = data, aes(fill=group, x=variable, y=value)) +
  geom_bar(position="dodge", stat = "identity") +
  geom_text(aes(label=value), position=position_dodge(width=0.9), vjust=-0.2, size = 5) +
  labs(x = "") +
  labs(y="Proportion (%)") +
  theme(legend.title = element_blank(), legend.position = "bottom") +
  theme(axis.text.x = element_text(size=12, color = "black")) +
  theme(axis.text.y = element_text(size = 12)) +
  theme(legend.text = element_text(size = 12)) +
  theme(axis.title.y = element_text(size = 12)) +
  scale_y_continuous(limits = c(0,60))  +
  annotate(geom="text", x=3, y=50, label="<0.001",
           color="black") +
  annotate(geom="text", x=2, y=50, label="<0.001",
           color="black") + 
  annotate(geom="text", x=1, y=50, label="<0.001",
           color="black")

Upvotes: 1

Will Oldham
Will Oldham

Reputation: 1054

I usually solve this problem by adding a geom_text layer with my p-values and labels from a different data frame. You have to move the fill aesthetic to the geoms that use it since it is not present in the annot data frame. The advantage of this is you can develop pipelines to calculate p-values and insert them programmatically. By setting ypos to Inf with vjust, the text should always be near the top of the graph. This should work:

annot <- 
  tibble(
    variable = c("X", "Y", "Z"), 
    label = rep("< 0.001", 3), 
    ypos = Inf, 
    vjustvar = 2
  )

ggplot(data = data, aes(x=variable, y=value)) +
  geom_bar(aes(fill = group), position="dodge", stat = "identity") +
  geom_text(aes(fill = group, label=value), position=position_dodge(width=0.9), vjust=-0.2, size = 5) +
  geom_text(
    data = annot, 
    aes(label = label, y = ypos, vjust = vjustvar)
  ) +
  labs(x = "") +
  labs(y="Proportion (%)") +
  theme(legend.title = element_blank(), legend.position = "bottom") +
  theme(axis.text.x = element_text(size=12, color = "black")) +
  theme(axis.text.y = element_text(size = 12)) +
  theme(legend.text = element_text(size = 12)) +
  theme(axis.title.y = element_text(size = 12)) +
  scale_y_continuous(limits = c(0,60)) 

Upvotes: 1

Related Questions