Showing all x axis label for discrete variable in ggplot bar plot

Viewed 1971

I have a set of data and I want to plot a bar plot for the data. The example of data is shown below:

   yq        flag      n ratio
   <yearqtr> <fct> <int> <dbl>
 1 2011 Q1   0       269 0.610
 2 2011 Q1   1       172 0.390
 3 2011 Q2   0       266 0.687
 4 2011 Q2   1       121 0.313
 5 2011 Q3   0       239 0.646
 6 2011 Q3   1       131 0.354
 7 2011 Q4   0       153 0.668
 8 2011 Q4   1        76 0.332
 9 2012 Q1   0       260 0.665
10 2012 Q1   1       131 0.335
11 2012 Q2   0       284 0.676
12 2012 Q2   1       136 0.324
13 2012 Q3   0       197 0.699
14 2012 Q3   1        85 0.301
15 2012 Q4   0       130 0.688
16 2012 Q4   1        59 0.312
17 2013 Q1   0       273 0.705
18 2013 Q1   1       114 0.295
19 2013 Q2   0       333 0.729
20 2013 Q2   1       124 0.271

What I want to do is basically plotting the ratio for each flag in each quarter. I wrote the code below:

data$flag <- as.factor(data$flag)
ggplot(data=data, aes(x=yq, y=ratio, fill=flag)) +
  geom_bar(stat="identity", color="black", position=position_dodge())+
  theme_minimal() +
  scale_fill_manual(values=c('#999999','#E69F00'))

The result is shown below:

result of code

But what I actually want is to show all quarters on the x-axis and maybe in vertical form for better visualization. I tried using scale_x_discrete(limits=yq) however, this is not the correct answer and return an error. How can I do this?

3 Answers

It looks like your yq column is in year-quarter format (as defined in the zoo package). For ggplot, it might be best to convert this to date format and specify the breaks like this:

library(ggplot2)
library(zoo)

data$flag <- as.factor(data$flag)

ggplot(data=data, aes(as.Date(yq), ratio, fill = flag)) +
  geom_col(color="black", position = position_dodge()) +
  scale_x_date(date_breaks = "3 months", guide = guide_axis(n.dodge = 2)) +
  labs(x = "Year / Quarter") +
  scale_fill_manual(values=c('#999999','#E69F00')) +
  theme_minimal() 

Or you could stack the columns:


ggplot(data=data, aes(as.Date(yq), ratio, fill = flag)) +
  geom_col(color="black", position = position_stack()) +
  scale_x_date(date_breaks = "3 months", guide = guide_axis(n.dodge = 2)) +
  labs(x = "Year / Quarter") +
  scale_fill_manual(values=c('#999999','#E69F00')) +
  theme_minimal() 

Data

data <- structure(list(yq = structure(c(2011, 2011, 2011.25, 2011.25, 
2011.5, 2011.5, 2011.75, 2011.75, 2012, 2012, 2012.25, 2012.25, 
2012.5, 2012.5, 2012.75, 2012.75, 2013, 2013, 2013.25, 2013.25
), class = "yearqtr"), flag = c(0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 
0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L), n = c(269L, 
172L, 266L, 121L, 239L, 131L, 153L, 76L, 260L, 131L, 284L, 136L, 
197L, 85L, 130L, 59L, 273L, 114L, 333L, 124L), ratio = c(0.61, 
0.39, 0.687, 0.313, 0.646, 0.354, 0.668, 0.332, 0.665, 0.335, 
0.676, 0.324, 0.699, 0.301, 0.688, 0.312, 0.705, 0.295, 0.729, 
0.271)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame"))

Maybe try this:

library(tidyverse)
#Code
df %>% 
  mutate(yq=factor(yq,levels = rev(unique(yq)),ordered = T)) %>%
  ggplot(aes(x=yq, y=ratio, fill=factor(flag))) +
  geom_bar(stat="identity", color="black", position=position_dodge())+
  theme_minimal() +
  scale_x_discrete(breaks=unique(df$yq))+
  scale_fill_manual(values=c('#999999','#E69F00'))+
  coord_flip()+labs(fill='flag')

Output:

enter image description here

Or this:

#Code 2
df %>% 
  ggplot(aes(x=yq, y=ratio, fill=factor(flag))) +
  geom_bar(stat="identity", color="black", position=position_dodge())+
  theme_minimal() +
  scale_x_discrete(breaks=unique(df$yq))+
  scale_fill_manual(values=c('#999999','#E69F00'))+
  theme(axis.text.x = element_text(angle=90))+labs(fill='flag')

Output:

enter image description here

Some data used:

#Data
df <- structure(list(yq = c("2011 Q1", "2011 Q1", "2011 Q2", "2011 Q2", 
"2011 Q3", "2011 Q3", "2011 Q4", "2011 Q4", "2012 Q1", "2012 Q1", 
"2012 Q2", "2012 Q2", "2012 Q3", "2012 Q3", "2012 Q4", "2012 Q4", 
"2013 Q1", "2013 Q1", "2013 Q2", "2013 Q2"), flag = c(0, 1, 0, 
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1), n = c(269, 
172, 266, 121, 239, 131, 153, 76, 260, 131, 284, 136, 197, 85, 
130, 59, 273, 114, 333, 124), ratio = c(0.61, 0.39, 0.687, 0.313, 
0.646, 0.354, 0.668, 0.332, 0.665, 0.335, 0.676, 0.324, 0.699, 
0.301, 0.688, 0.312, 0.705, 0.295, 0.729, 0.271)), row.names = c(NA, 
-20L), class = "data.frame")

I am guessing you are using zoo package, then set the scale_x_yearqtr with custom breaks:

ggplot(data = data, aes(x = yq, y = ratio, fill = flag)) +
  geom_bar(stat = "identity", color = "black", position = position_dodge())+
  scale_x_yearqtr(breaks = unique(data$yq)) +
  theme_minimal() +
  scale_fill_manual(values = c('#999999', '#E69F00'))

enter image description here

Then if needed just flip:

ggplot(data = data, aes(x = yq, y = ratio, fill = flag)) +
  geom_bar(stat = "identity", color = "black", position = position_dodge())+
  scale_x_yearqtr(breaks = unique(data$yq)) +
  theme_minimal() +
  scale_fill_manual(values = c('#999999', '#E69F00')) +
  coord_flip()

enter image description here

Data

> dput(data)
structure(list(yq = structure(c(2011, 2011, 2011.25, 2011.25, 
2011.5, 2011.5, 2011.75, 2011.75, 2012, 2012, 2012.25, 2012.25, 
2012.5, 2012.5, 2012.75, 2012.75, 2013, 2013, 2013.25, 2013.25
), class = "yearqtr"), flag = structure(c(1L, 2L, 1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("0", 
"1"), class = "factor"), n = c(269L, 172L, 266L, 121L, 239L, 
131L, 153L, 76L, 260L, 131L, 284L, 136L, 197L, 85L, 130L, 59L, 
273L, 114L, 333L, 124L), ratio = c(0.61, 0.39, 0.687, 0.313, 
0.646, 0.354, 0.668, 0.332, 0.665, 0.335, 0.676, 0.324, 0.699, 
0.301, 0.688, 0.312, 0.705, 0.295, 0.729, 0.271)), row.names = c(NA, 
-20L), class = "data.frame")
Related