Meg
Meg

Reputation: 39

How can I label the groups of bars on the x-axis?

How can I add labels to the groups of bars on the x- axis (which is the left side of the graph)? It is easy to label the entire axis, or to allow the labels to be generated based on the data, but I am unable to figure out how to label each group of bars, if that makes sense.

I know I could recode the item data into complete sentences, but that seems inelegant relative to making some change to the ggplot code.

I have tried using the code from a similar question on this site (Customize axis labels) scale_x_discrete(breaks = 1:5, labels=c("foo","bar","baz","phi","fum")) + but it simply causes all of the labels to disappear from my graph, and I'm not sure why. That result is worse than using scale_x_discrete(waiver()) +

First, load libraries + color palette:

library(ggplot2)
library(tidyverse)
cbPalette <- c("#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")

And given the following data:

item <- c("none","none","none",
          "low", "low", "low", 
          "moderatelow","moderatelow","moderatelow",
          "moderate","moderate","moderate",
          "greatest","greatest","greatest")

mean <- c(2.566, 2.873, 3.286, # none - Scenario A
          3.911, 4.123, 4.519, # low - Scenario B
          4.113, 4.169, 4.174, # moderatelow - Scenario C
          3.88, 3.589, 3.2,    # moderate - Scenario D
          3.065, 2.544, 2.107) # greatest - Scenario E

reg <- c("GP", "hunt", "trap",
         "GP", "hunt", "trap",
         "GP", "hunt", "trap",
         "GP", "hunt", "trap",
         "GP", "hunt", "trap")

mydata <- data.frame(item, mean, reg)

I used the following code to generate the figure

ggplot(mydata, aes(x = item, y = mean, fill = reg)) + 
  ggtitle("How acceptable are each of the following scenarios to you?")+
  coord_flip() + 
  geom_bar(position = "dodge", stat = "identity") + 
  # facet_wrap(~item, scales = "free_x") +   # changed
  scale_fill_manual(values=cbPalette) +
  # scale_fill_grey(start = 0.8, end = 0.2) +
  ylab("1 = highly unacceptable, 7 = highly acceptable") + 
  xlab("") + 
  theme_bw() +
  #theme(legend.position="bottom")+ 
  scale_x_discrete(waiver()) + 
  labs(fill="reg")

Here is the resulting figure: enter image description here

ETA something for the millionth time - I figured out what works for me, which is using

  ggtitle("How acceptable are each of the following scenarios to you?")+
  coord_flip() + 
  geom_bar(position = "dodge", stat = "identity") + 
  # facet_wrap(~item, scales = "free_x") +   # changed
  scale_fill_manual(values=cbPalette) +
  # scale_fill_grey(start = 0.8, end = 0.2) +
  ylab("1 = highly unacceptable, 7 = highly acceptable") + 
  xlab("") + 
  theme_bw() +
  #theme(legend.position="bottom")+ 
  scale_x_discrete(breaks=c("none", "low", "moderatelow", "moderate", "greatest"),
                   labels=c("Control", "Treat 1", "Treat 2", "slkdj", "adkljf")) + 
  labs(fill="reg")

Thank you so much to those of you who commented! Your help led me to the answer.

ETA - okay here I am, back again. It was pointed out to me by @Gregor Thomas that my scale limits are set incorrectly, along with the unnecessary nature of some of my code. This feedback is much appreciated. Using the guidance of commentors, I was able to resolve the labeling issue that existed.

But, now I cannot figure out how to adjust the limits of the axis in the new code format. Given the following, how can I set the scale from 1-7 to reflect the nature of the likert scale people responded to? See code below.

ggplot(mydata, aes(y = item, x = mean, fill = reg)) + 
  geom_col(position = "dodge") + 
  scale_fill_manual(values = cbPalette) +
  scale_y_discrete(breaks=c("none", "low", "moderatelow", "moderate", "greatest"),
                   labels=c("No wolves", "Very low numbers of wolves", "Moderately low numbers of wolves", "Moderate numbers of wolves", "Greatest numbers of wolves that can be sustained")
  ) + 
  scale_x_continuous(expand = expansion(mult = c(0, .05))) +
  labs(
    title = "How acceptable are each of the following scenarios to you?",
    x = "1 = highly unacceptable, 7 = highly acceptable",
    y = "",
    fill = "population"
  ) +
  theme_bw() +
  theme(
    legend.position = "bottom",
    panel.grid.major.y = element_blank()
  )

Upvotes: 1

Views: 1338

Answers (2)

Gregor Thomas
Gregor Thomas

Reputation: 145765

Here's how I'd clean up your code. I skip the coord_flip, just mapping the x and y variables as desired. I consolidate all the labels into labs(), and I use scale_y_discrete(labels = ) for the labels.

my_labels = rev(paste("Scenario", LETTERS[1:5]))

ggplot(mydata, aes(y = item, x = mean, fill = reg)) + 
  geom_col(position = "dodge") + 
  scale_fill_manual(values = cbPalette) +
  scale_y_discrete(
    labels = my_labels
  ) + 
  labs(
    title = "How acceptable are each of the following scenarios to you?",
    x = "1 = highly unacceptable, 7 = highly acceptable",
    y = "",
    fill = "population"
  ) +
  theme_bw() +
  theme(legend.position = "bottom")

enter image description here

If this were my plot, I'd adjust the x-scale to remove the padding below 0, and I'd remove the y gridlines, like this:

ggplot(mydata, aes(y = item, x = mean, fill = reg)) + 
  geom_col(position = "dodge") + 
  scale_fill_manual(values = cbPalette) +
  scale_y_discrete(
    labels = my_labels
  ) + 
  scale_x_continuous(expand = expansion(mult = c(0, .05))) +
  labs(
    title = "How acceptable are each of the following scenarios to you?",
    x = "1 = highly unacceptable, 7 = highly acceptable",
    y = "",
    fill = "population"
  ) +
  theme_bw() +
  theme(
    legend.position = "bottom",
    panel.grid.major.y = element_blank()
  )

enter image description here

Though if 1 is "highly unacceptable", I don't know how to interpret 0... the whole x scale is seems confusing. Maybe you should set the x limits to be from 1 to 7, not 0 to max of data (which is 5)? If so, use scale_x_continuous(expand = expansion(mult = c(0, .05)), limits = c(1, 7)).

Upvotes: 2

TarJae
TarJae

Reputation: 78927

We could add facet_grid(item ~ ., scales="free_y", space="free_y", switch="y")

ggplot(mydata, aes(x = item, y = mean, fill = reg)) + 
  ggtitle("How acceptable are each of the following scenarios to you?")+
  coord_flip() + 
  geom_bar(position = "dodge", stat = "identity") + 
  # facet_wrap(~item, scales = "free_x") +   # changed
  scale_fill_manual(values=cbPalette) +
  # scale_fill_grey(start = 0.8, end = 0.2) +
  ylab("1 = highly unacceptable, 7 = highly acceptable") + 
  xlab("") + 
  theme_bw() +
  theme(legend.position="bottom")+ 
  scale_x_discrete(breaks = NULL) + 
  labs(fill="population") +
  facet_grid(item ~ ., scales="free_y", space="free_y", switch="y") +
  guides(fill=FALSE)

enter image description here

Upvotes: 1

Related Questions