2

I have a stacked graph where I already have 2 variables. I want to add a third variable as symbols or objects in the graph. This is my desired graph:

desired graph

My current code is:

sur %>% 
  filter(!(species_broad %in% c("Monkey", "Cattle"))) %>%
  drop_na(circumstances_bite_broad_intended) %>%
  add_count(species_broad) %>%
  mutate(y_species_broad = 
           reorder(
             factor(paste0(species_broad, "\n", "(n = ", n, ")")),
             as.numeric(species_broad)
           )) %>% 
  ggplot(mapping=aes(y= y_species_broad, fill=circumstances_bite_broad_intended)) + 
  geom_bar(colour="black" , position = "fill")+
  scale_x_continuous (labels=c("0","25%","50%","75%","100%"))  +
  labs (x="Proportion of responses",y="Animal species" , fill="Circumstances")+  # "fill" to change the legend title 
  ggtitle ("Circumstances of bite in different animal species")+ 
  scale_fill_manual( values =c ("Threatening Engagement" = "darkred" ,
                                "Friendly Engagement" = "red" , 
                                "Practical Engagement" = "#EC7979" ,
                                "Unintentional Human Engagement" = "lightblue" ,
                                "Apparently unprovoked" = "darkblue"))

My data is:

structure(list(species = structure(c(1L, 1L, 3L, 5L, 1L, 2L, 
7L, 2L, 2L, 1L, 3L, 1L, 2L, 3L, 1L, 2L, 1L, 4L, 4L, 7L, 2L, 1L, 
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 3L, 2L, 1L, 1L, 1L, 6L, 7L, 9L), levels = c("Pet dog", 
"Unowned dog", "Dog (unknown status)", "Pet cat", "Unowned cat", 
"Cat (unknown status)", "Rat/rodent", "Monkey", "Cattle"), class = "factor"), 
    circumstances_bite_avoidability = structure(c(1L, 2L, 1L, 
    1L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 2L, 
    1L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 
    1L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 
    2L, NA), levels = c("Avoidable", "Unavoidable"), class = "factor"), 
    circumstances_bite_broad_intended = structure(c(2L, 4L, 1L, 
    3L, 4L, 4L, 4L, 5L, 5L, 3L, 5L, 1L, 4L, 5L, 5L, 1L, 5L, 5L, 
    2L, 5L, 4L, 3L, 5L, 2L, 2L, 5L, 4L, 3L, 3L, 5L, 1L, 5L, 1L, 
    1L, 5L, 5L, 4L, 4L, 5L, 1L, 5L, 5L, 1L, 1L, 5L, 5L, 2L, 3L, 
    5L, NA), levels = c("Threatening Engagement", "Friendly Engagement", 
    "Practical Engagement", "Unintentional Human Engagement", 
    "Apparently unprovoked"), class = "factor")), row.names = c(NA, 
50L), class = "data.frame")

  • `! object 'species_broad' not found`, do you mean `species` instead? (`names(sur)[1] <- "species_broad"` fixes it, no error) – r2evans Aug 12 '23 at 14:43
  • Interesting question, I think it's a duplicate of https://stackoverflow.com/q/62393159/3358272 (if you can use `ggpattern`) – r2evans Aug 12 '23 at 14:45

1 Answers1

4

With the provided data, we could do something like this (main feature is to use gemo_bar_pattern from ggpattern package. With some tricks in legend modification:

library(tidyverse)
library(ggpattern)

sur <- sur %>% 
  mutate(species = case_when(str_detect(species, "D|dog") ~ "Dog",
                               str_detect(species, "C|cat") ~ "Cat",
                               .default = "Rat/rodent")
         ) %>% 
  filter(!(species %in% c("Monkey", "Cattle"))) %>%
  drop_na(circumstances_bite_broad_intended) %>%
  add_count(species)

sur$y_species <- with(sur, reorder(
  factor(paste0(species, "\n", "(n = ", n, ")")),
  as.numeric(species)))

ggplot(sur, aes(y= y_species, fill=circumstances_bite_broad_intended, pattern = circumstances_bite_avoidability)) + 
  geom_bar_pattern(
    colour = "black", 
    position = "fill",
    pattern_density = 0.1,
    pattern_spacing = 0.015,
    pattern_key_scale_factor = 0.9
  ) +
  scale_x_continuous(labels=c("0","25%","50%","75%","100%")) +
  labs(x="Proportion of responses", y="Animal species", fill="Circumstances", pattern="Avoidability") +
  ggtitle("Circumstances of bite in different animal species") + 
  scale_fill_manual(values =c("Threatening Engagement" = "darkred",
                              "Friendly Engagement" = "red",
                              "Practical Engagement" = "#EC7979",
                              "Unintentional Human Engagement" = "lightblue",
                              "Apparently unprovoked" = "darkblue")) + 
  scale_pattern_manual(values=c("Avoidable" = "stripe", 
                                "Unavoidable" = "none")) +
  theme(legend.key = element_rect(fill = "white")) +
  guides(pattern = guide_legend(override.aes = list(fill = "white")),
         fill = guide_legend(override.aes = list(pattern = "none")))

enter image description here

TarJae
  • 72,363
  • 6
  • 19
  • 66