Home > Software engineering >  Any way to flip coordinates without reversing everything else?
Any way to flip coordinates without reversing everything else?

Time:12-28

I'm working on a plotting function that has the option to flip coordinates (using coord_flip). The thing is, this is a plot by group (using the fill argument), which means, for some reason, coord_flip also reverses colors, legend, my value column and my fill column. In practice, this means I have the following pice of code in my function:

  if(flip_coord){
    colors = c("#CC0000", "#002D73" ) %>% rev
    rev_legend = T
    table[[col_plot]] = fct_rev(table[[col_plot]]) # value column
    table[['origin_table']] = fct_rev(table[['origin_table']]) # fill column
    
  } else{
    colors = c("#CC0000", "#002D73" ) 
    rev_legend = F
  }

There's also this line in my plot:

{if(flip_coord) coord_flip()}  

This brings back everything else that gets scrambled with coord_flip, but isn't too elegant. Is there a better way to only flip coordinates without reversing everything else?

PS: I know there's no reproducible example here, I'll try to add one, but if someone has already stumbled upon the answer to this problem that might be common, I'll post as is for the moment.

Edit: made some reprex. Let's say my data is this:

df =  tibble(origin = c('2000s', '1990s') %>% rep(2),
             region = c('South', 'North') %>% rep(2) %>% sort,
             value = 1:4) %>% 
  mutate(origin = factor(origin, levels = c('1990s', '2000s')),
         region = factor(region, levels = c('North', 'South')))

colors = c('red', 'blue')

# origin region value
# <fct>  <fct>  <int>
# 1 2000s  North      1
# 2 1990s  North      2
# 3 2000s  South      3
# 4 1990s  South      4

If I plot regularly, everything comes ordered (90s first, 00s second, North first, South second):

    df  %>%
  ggplot(aes(x = region, fill = origin, y = value))  
  geom_bar(stat = "identity", position = 'dodge', color = "white", alpha= 0.8) 
  scale_fill_manual(values=colors)

a

But, if I flip coordinates (just adding coord_flip() to the code above) I get the following:

b

South above north, 00s above 90s and the legend isn't in the same order than the bars. This is exactly the same if I input x = value and y = origin. So, to fix this I have to do the following:

df2 = df
df2[['region']] = fct_rev(df2[['region']]) # Change 1
df2[['origin']] = fct_rev(df2[['origin']]) # Change 2

df2  %>%
  ggplot(aes(x = value, fill = origin, y = region))  
  geom_bar(stat = "identity", position = 'dodge', color = "white", alpha= 0.8)   
  guides(fill = guide_legend(reverse = T))   # Change 3
  scale_fill_manual(values=rev(colors)) # Change 4

Bringing the correct orders:

c

Is there any less cumbersome way to achieve this?

CodePudding user response:

The issue is that coord_flip() changes the ordering of bars within groups in grouped bar plot: According to enter image description here

CodePudding user response:

Coord flip does not flip everything around. Factors are plotted starting from the bottom. Thus, 1990 will be below 2000, and North will be below South.

The simplest way I can see is to simply reverse your factor levels. (when creating your factors).

library(tidyverse)
df <- tibble(
  origin = c("2000s", "1990s") %>% rep(2),
  region = c("South", "North") %>% rep(2) %>% sort(),
  value = 1:4
) %>%
  mutate(
    ## just reverse the factor levels
    origin = factor(origin, levels = rev(c("1990s", "2000s"))),
    region = factor(region, levels = rev(c("North", "South")))
  )

colors <- c("red", "blue")

df %>%
  # switched x and y
  ggplot(aes(y = region, x = value, fill = origin))  
  geom_bar(stat = "identity", position = "dodge", color = "white", alpha = 0.8)  
## this is to set the correct legend order and mapping to your colors
  scale_fill_manual(values = colors, breaks = rev(unique(df$origin))) 

  • Related