0

I am trying to add separate text for each bar to show statistical significance. Can someone please show me how I can add separate text onto each bar in facet? Also why text of a-axis on the last facet is cutting short? Also I am thankful to previous contributor for the code improvement. Here is my code:

library(viridis)
library(tidyr)
library(dplyr)
library(tibble)
library(ggplot2)

df <- data.frame(
  H1 = c(6.36, 3.03, 6.85, 4.07, 4.69, 6.27, 6.67, 3.11, 5.07, 6.14, 5.93, 6.49),
  H2 = c(5.15, 5.00, 5.71, 5.50, 4.99, 5.81, 6.05, 5.76, 5.28, 5.69, 5.69, 5.06),
  H3 = c(3.85, 5.13, 4.99, 4.91, 5.01, 5.73, 5.77, 5.94, 5.57, 5.35, 6.00, 4.39),
  H4 = c(3.84, 4.80, 5.15, 4.85, 4.99, 5.73, 5.77, 5.45, 5.44, 5.41, 5.81, 4.46),
  H5 = c(4.08, 5.17, 4.77, 5.03, 5.00, 5.49, 5.49, 5.80, 5.51, 5.18, 5.76, 4.60),
  H6 = c(4.35, 5.59, 5.59, 4.83, 5.52, 5.63, 5.85, 5.74, 5.66, 5.19, 5.79, 4.84), fontface = c("bold"),
  names = c("RB", "Ver", "Atl", "POR12PG28-3",
            "Valery", "Rio", "CO99076-6R", "Purple",
            "AC99330-1P/Y", "CO05068-1RU", "Masquerade", "Canela"),
  specie = c(rep("Appearance", 12), rep("Aroma" , 12), rep("Flavor" , 12),
             rep("Overall" , 12), rep("Aftertaste", 12), rep("Texture", 12)),
  condition = rep(c("RB", "Ver", "Atl", "POR12PG28-3",
                    "Valery", "Rio", "CO99076-6R", "Purple",
                    "AC99330-1P/Y", "CO05068-1RU", "Masquerade", "Canela") , 6))

df <- df %>%
  pivot_longer(starts_with("H"), names_to = "h.names")


#one condition per plot
nameframe <- enframe(unique(df$h.names))
specieframe <- enframe(unique(df$specie))
names.labs <- c("Appearance", "Aroma", "Flavor", "Overall", "Aftertaste", "Texture")
names(names.labs) <- c("H1", "H2", "H3", "H4", "H5", "H6")


#add text onto each bar
df <- df %>% 
  arrange(desc(names)) %>% 
  group_by(names) %>% 
  mutate(
    bar_labels = case_when(
      names == "Ver" ~ "ab",
      names == "Valery" ~ "e",
      names == "Rio" ~ "a",
      names == "RB" ~ "d",
      names == "Purple" ~ "cd",
      names == "POR12PG28-3" ~ "ab",
      names ==  "Masquerade" ~ "ab",
      names == "CO99076-6R" ~ "e",
      names == "CO05068-1RU" ~ "c",
      names == "Canela" ~ "ab",
      names == "Atl" ~ "b",
      names == "AC99330-1P/Y" ~ "ab",
      TRUE ~ as.character(NA)
    ))

ggplot(data = df, mapping = aes(x = names, y = value)) +
  geom_col(position = "dodge") +
  coord_flip() +
  ylim(c(0,9)) +
  scale_y_continuous(breaks=seq(0.0, 9, 3), limits=c(0, 9), labels = c("0", "3", "6", "Like\nExtremely")) +
  labs(y = "", x = "") + theme(legend.title = element_blank(), axis.text.y = element_text(face = "bold", size = 11),
                               axis.text.x = element_text(face = "bold", size = 9)) +
  scale_fill_discrete(breaks = c("Appearance", "Aroma", "Flavor", "Overall", "Aftertaste", "Texture")) +
  facet_wrap(~h.names, labeller = labeller(h.names = names.labs)) +
  geom_text(aes(label = bar_labels, hjust = 0))
Phil
  • 7,287
  • 3
  • 36
  • 66
chetan
  • 9
  • 4
  • Since ggplot are durable objects and really just lists of command and names, you should be able to reverse the process of this answer: https://stackoverflow.com/questions/65978711/how-to-extract-bar-labels-and-their-size-from-a-given-ggplot-object – IRTFM Mar 13 '21 at 02:19
  • Are you asking about how to calculate statistical significance (of what?), or how to put arbitrary text into a facet? There might be an addin that does some version of both, but it would help to get more specific understanding of your goal. – Jon Spring Mar 13 '21 at 02:57
  • I just want arbitrary text. – chetan Mar 13 '21 at 21:52
  • @JonSpring Can you please help? I tried but it is not working. – chetan Mar 27 '21 at 02:52
  • You are already adding the bar labels to each bar in each facet -- can you describe more how what you want is different from that? – Jon Spring Mar 27 '21 at 08:39
  • @JonSpring Thanks for the response. Yes, I already have bar labels but they are replicating same label, say "a" onto each bar in each facet. So suppose sample Ver in Appearance facet is statistically different, I shall put label "a" and in Facet 2, say Aroma the same sample is "ab". But currently it is replicating same "a" in all facets with respect to that sample. So , i wish to have different labels onto each bar with respect to same sample. – chetan Mar 27 '21 at 20:47

1 Answers1

0

First, I took a subset of the data to make there be one observation for each bar I want to plot and label with an important_label. It seems like the data set in question has 6 identical copies of each line when we just look at the variables that feed into the plot: h.names, names, and value.

You can see this replication by replacing in the OP geom_col(position = "dodge") + with geom_jitter() + or by running df %>% count(h.names, names, value).


df2 <- df %>%
  distinct(h.names, names, value) %>%
  mutate(custom_label = 1:n())

Then I plotted the bars with a geom_text layer labeled with the custom_label. To keep the rightmost axis text from cutting off, I changed the horizontal alignment of the axis text in the theme, making it 0.5 (center) for the first three values and mostly right-aligned for the last label. Adjust to taste. Alternatively, you could add some right margin to the whole plot, I think with theme(plot.margin = ....

ggplot(data = df2, mapping = aes(x = names, y = value)) +
  geom_col(position = "dodge") +
  geom_text(aes(label = custom_label), hjust = -0.2) +
  coord_flip() +
  ylim(c(0,9)) +
  scale_y_continuous(breaks=seq(0.0, 9, 3), limits=c(0, 9), labels = c("0", "3", "6", "Like\nExtremely")) +
  labs(y = "", x = "") + theme(legend.title = element_blank(), axis.text.y = element_text(face = "bold", size = 11),
                               axis.text.x = element_text(face = "bold", size = 9)) +
  scale_fill_discrete(breaks = c("Appearance", "Aroma", "Flavor", "Overall", "Aftertaste", "Texture")) +
  facet_wrap(~h.names, labeller = labeller(h.names = names.labs)) +
  theme(axis.text.x = element_text(hjust = c(rep(0.5,3), 0.8)))

enter image description here

Jon Spring
  • 55,165
  • 4
  • 35
  • 53