Yellow_truffle
Yellow_truffle

Reputation: 923

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

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?

Upvotes: 4

Views: 3519

Answers (3)

zx8754
zx8754

Reputation: 56249

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")

Upvotes: 2

Allan Cameron
Allan Cameron

Reputation: 174506

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"))

Upvotes: 3

Duck
Duck

Reputation: 39613

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")

Upvotes: 2

Related Questions