Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixing the order of facets in ggplot

People also ask

What are facets in Ggplot?

The facet approach partitions a plot into a matrix of panels. Each panel shows a different subset of the data. This R tutorial describes how to split a graph using ggplot2 package. There are two main functions for faceting : facet_grid()

What is facet wrap in ggplot2?

facet_wrap() makes a long ribbon of panels (generated by any number of variables) and wraps it into 2d. This is useful if you have a single variable with many levels and want to arrange the plots in a more space efficient manner. You can control how the ribbon is wrapped into a grid with ncol , nrow , as.

What is the function of Facet_grid () in Ggplot ()?

facet_grid() forms a matrix of panels defined by row and column faceting variables. It is most useful when you have two discrete variables, and all combinations of the variables exist in the data.


Make your size a factor in your dataframe by:

temp$size_f = factor(temp$size, levels=c('50%','100%','150%','200%'))

Then change the facet_grid(.~size) to facet_grid(.~size_f)

Then plot: enter image description here

The graphs are now in the correct order.


There are a couple of good solutions here.

Similar to the answer from Harpal, but within the facet, so doesn't require any change to underlying data or pre-plotting manipulation:

# Change this code:
facet_grid(.~size) + 
# To this code:
facet_grid(~factor(size, levels=c('50%','100%','150%','200%')))

This is flexible, and can be implemented for any variable as you change what element is faceted, no underlying change in the data required.


Even less manipulating: facet_grid(~fct_relevel(size,'50%','100%','150%','200%'))


Here's a solution that keeps things within a dplyr pipe chain. You sort the data in advance, and then using mutate_at to convert to a factor. I've modified the data slightly to show how this solution can be applied generally, given data that can be sensibly sorted:

# the data
temp <- data.frame(type=rep(c("T", "F", "P"), 4),
                    size=rep(c("50%", "100%", "200%", "150%"), each=3), # cannot sort this
                    size_num = rep(c(.5, 1, 2, 1.5), each=3), # can sort this
                    amount=c(48.4, 48.1, 46.8, 
                             25.9, 26.0, 24.9,
                             20.8, 21.5, 16.5,
                             21.1, 21.4, 20.1))

temp %>% 
  arrange(size_num) %>% # sort
  mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>% # convert to factor

  ggplot() + 
  geom_bar(aes(x = type, y=amount, fill=type), 
           position="dodge", stat="identity") + 
  facet_grid(~ size)

You can apply this solution to arrange the bars within facets, too, though you can only choose a single, preferred order:

    temp %>% 
  arrange(size_num) %>%
  mutate_at(vars(size), funs(factor(., levels=unique(.)))) %>%
  arrange(desc(amount)) %>%
  mutate_at(vars(type), funs(factor(., levels=unique(.)))) %>%
  ggplot() + 
  geom_bar(aes(x = type, y=amount, fill=type), 
           position="dodge", stat="identity") + 
  facet_grid(~ size)


  ggplot() + 
  geom_bar(aes(x = type, y=amount, fill=type), 
           position="dodge", stat="identity") + 
  facet_grid(~ size)

Similar to answer from glenn_in_boston, but without hard coding in the levels.

# Change this code:
facet_grid(.~size) + 
# To this code:
facet_grid(~factor(size, levels=unique(df$size)))

Works because size is arranged from the smallest to the largest in the dataframe.

If size was already a factor and you just want to flip the order when plotting, this is an option:

# Updating dataframe so size is a factor ordered smallest to largest
df <- data.frame(
  type   = c("T", "F", "P", "T", "F", "P", "T", "F", "P", "T", "F", "P"), 
  size   = factor(c("50%", "50%", "50%", "100%", "100%", "100%", "150%", "150%", "150%", "200%", "200%", "200%"), levels=c("50%", "100%","150%","200%"), ordered = TRUE),
  amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)

# Now plotting with facets in the reverse order
ggplot(df, aes(type, amount , fill=type, group=type, shape=type, facets=size)) + 
  geom_col(width=0.5, position = position_dodge(width=0.6)) + 
  facet_grid(~factor(size, levels=rev(unique(df$size)))) +  #this part updated
  theme_bw() + 
  scale_fill_manual(values = c("darkblue","steelblue1","steelblue4"), 
                    labels = c("T", "F", "P"))