Reputation: 39
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")
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
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")
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()
)
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
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)
Upvotes: 1