2

I have a dataframe with below structure

structure(list(Set = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("Set2", 
"Set1"), class = "factor"), Subset = c("Feminine", "Masculine", 
"Neutral", "Feminine", "Masculine", "Neutral"), Genderity = c(4.47, 
-3.65, 1.54, 4.13, -4.03, -0.61)), row.names = c(NA, -6L), class = "data.frame")

I want to plot a likert scale sort of plot as below output Expected Likert image output

I am struggling to replicate this in ggplot 2 (below is my code, even though it gives similar output as expected The spaces in y axis are way off because I used Genderity in both x & y argument). It was giving me error if I left y argument blank

ggplot(aes(x=Genderity, y=Genderity), data=df_2, position="stack", stat="identity")+
  geom_bar(stat="identity",aes(fill=Subset),position="dodge")+
  coord_flip()+
  geom_hline(yintercept = 0, color =c("black")) +
  scale_y_continuous(breaks=seq(-5,5,1), limits=c(-5,5))+
  facet_wrap(facets = .~Set, ncol = 2, nrow=1)

Output ggplot from my code My Output

I know my output is really close to what I want but its not the right way to do it. Please help how to do this via ggplot 2

Vaibhav Singh
  • 1,159
  • 1
  • 10
  • 25

2 Answers2

3

This seems like a good place to convert your Subset character string into a factor, which will let you sort it as you wish. Note, in defining the mapping, I used fct_rev to get the Feminine bar to be on top, to line up with the legend, which shows the factors in order.

df_2_mod <- df_2 %>%
  mutate(Subset = fct_relevel(Subset, "Feminine", "Neutral", "Masculine"))

ggplot(df_2_mod,
   aes(x=Subset %>% fct_rev(), y=Genderity, fill = Subset))+
geom_col()+  # geom_col uses values by default, vs. counts for geom_bar
coord_flip()+
geom_hline(yintercept = 0, color =c("black")) +
facet_wrap(facets = .~Set, nrow=1) +
labs(x="")

enter image description here

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

We can try a workaround:

# add a fake column
df_2$fake <-rownames(df_2)

library(ggplot2)

# we add as x the fake
ggplot(aes(x=fake, y=Genderity), data=df_2, position="stack")+
  geom_bar(stat="identity",aes(fill=Subset),position="dodge")+
  coord_flip()+
  geom_hline(yintercept = 0, color =c("black")) +
  scale_y_continuous(breaks=seq(-5,5,1), limits=c(-5,5))+
# to avoid riffle, we use the scales="free" option
  facet_wrap(facets = .~Set, ncol = 2, nrow=1,scales="free")+
# last, we make blank the y axis
  theme(axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank())

enter image description here

And, if you want the order in your mock-up and if you want also the x-axis blank, you can try this:

# the reorder option:
ggplot(aes(x=reorder(fake,Genderity), y=Genderity), data=df_2, position="stack")+
  geom_bar(stat="identity",aes(fill=Subset),position="dodge")+
  coord_flip()+
  geom_hline(yintercept = 0, color =c("black")) +
  scale_y_continuous(breaks=seq(-5,5,1), limits=c(-5,5))+
  facet_wrap(facets = .~Set, ncol = 2, nrow=1,scales="free")+
  theme(axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        # x-axis blank:
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank())

enter image description here

And:

+ ggtitle("Conveyed gender")

Will give you the title.

Edit:
to add labels, you've to:

    p <- ggplot(aes(x=reorder(fake,Genderity), y=Genderity), data=df_2, position="stack")+
  geom_bar(stat="identity",aes(fill=Subset),position="dodge")+
  coord_flip()+
  geom_hline(yintercept = 0, color =c("black")) +
  scale_y_continuous(breaks=seq(-5,5,1), limits=c(-5,5))+
  facet_wrap(facets = .~Set, ncol = 2, nrow=1,scales="free")+
  theme(axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        # x-axis blank:
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank())
p <- p + ggtitle("Conveyed gender") + geom_text(aes(label=Genderity), hjust=1)
p

enter image description here

Or you can use also:

+ geom_text(aes(label = Genderity), position = position_dodge(0.9))
s__
  • 9,270
  • 3
  • 27
  • 45
  • Can you please show me how to add labels next to bars as well – Vaibhav Singh Sep 10 '18 at 09:49
  • @Artika updated the answer, it should work also with the other answer. – s__ Sep 10 '18 at 10:08
  • HI In this my label is getting blocked as the color of my neutral is black and text color is also. I can't see it as it is falling inside the graph – Vaibhav Singh Sep 10 '18 at 11:18
  • @Artika I've updated with the ouput given by my code. Sorry, I did not understood what you'd like to modify, if you need other explaination, please ask me again in other word. – s__ Sep 10 '18 at 11:28
  • The value 1.54,4.47,4.13 which are falling inside the bar, I want them to be like -0.61 just outside the bar. So basically I want all the values to in position which green bars have just on top of bar – Vaibhav Singh Sep 10 '18 at 11:44
  • Try to see the last row of code `+ geom_text(aes(label = Genderity), position = position_dodge(0.9))` instead of `+ geom_text(aes(label=Genderity), hjust=1)`. In that case the labels are not on the top, but they are consistent in the bars. – s__ Sep 10 '18 at 12:01