Home > Software design >  ggplot - Manually Rearrange Order of X-Axis Levels
ggplot - Manually Rearrange Order of X-Axis Levels

Time:06-29

I have technically seen answers to this question several times looking through SO, but my situation is a bit of a special case. I am trying to create a line plot for means of 8 variables:

    > reshape2::melt(CON_FCCFCNC_summary)
No id variables; using all as measure variables
      variable     value
1    FCC_Faces 0.8252825
2   FCNC_Faces 0.7099912
3  FCC_Objects 0.8046462
4 FCNC_Objects 0.7661013
5   FCC_Scenes 0.8662500
6  FCNC_Scenes 0.8325000
7    FCC_Words 0.7778962
8   FCNC_Words 0.7106731

FCC and FCNC refer to distinct types of cognitive test. I want a line plot which keeps this exact order (both Faces, then both Objects, etc...), but colours the points on the line plot for the FCC and FCNC tests differently. My initial attempt was to simply have two different calls to geom_point and geom_line for each of the 4 FCC and FCNC tests:

ggplot(data = reshape2::melt(CON_FCC_summary))  
    geom_line(mapping = aes(x = variable, y = value, group = 1))   
    geom_point(mapping = aes(x = variable, y = value, group = 1))  
    geom_line(data = reshape2::melt(CON_FCNC_summary), mapping = aes(x = variable, y = value, group = 1))   
    geom_point(data = reshape2::melt(CON_FCNC_summary), mapping = aes(x = variable, y = value, group = 1)) 

While this does work, the variables are of course in the wrong order:

Incorrect FCC FCNC test order on X axis

As mentioned, I want to keep the original order of the tests which would involve interleaving the FCC and FCNC lines/points. If I try to specify the level directly in the final geom_point() aes(), I get an error because I am specifying more levels (8) than exist in the separate summary df's (4).

I need this for work and would be hugely grateful if anybody could help with this. Really, if anyone knows how to colour every other point on the geom_point plot, then I wouldn't need to separate the summary data at all which would make for a much more straightforward fix. If there is no way to do this (I would be surprised), then any help rearranging the X-axis into the order I need would be perfect. Thank you!

CodePudding user response:

Not 100% sure about your desired result but if I understand you right you could first separate your variable column into its two parts so that you could map the what (Faces, Objects, ...). on x and the type of test on color. Additionally in that case there is no need for a duplicated geom_line and ..._point:


library(ggplot2)
library(tidyr)

CON_FCCFCNC_summary_melt <- CON_FCCFCNC_summary_melt |>
  tidyr::separate(variable, into = c("type", "what"), remove = FALSE)

ggplot(data = CON_FCCFCNC_summary_melt, aes(x = what, y = value, group = type))  
  geom_line()  
  geom_point(aes(color = type))

DATA

CON_FCCFCNC_summary_melt <- structure(list(variable = c(
  "FCC_Faces", "FCNC_Faces", "FCC_Objects",
  "FCNC_Objects", "FCC_Scenes", "FCNC_Scenes", "FCC_Words", "FCNC_Words"
), value = c(
  0.8252825, 0.7099912, 0.8046462, 0.7661013, 0.86625,
  0.8325, 0.7778962, 0.7106731
)), class = "data.frame", row.names = c(
  "1",
  "2", "3", "4", "5", "6", "7", "8"
))

CodePudding user response:

If I understand you correctly, you want to compare the FCC and FCNC points within each object type. In which case, it would be better to separate the object type into its own variable and FCC/FCNC into a different variable, since conceptually these are two different variables. To plot this, I might do something like this:

melted <- reshape2::melt(CON_FCC_summary)

tidyr::separate(melted, variable, into = c('Var1', 'Var2'), sep = '_') %>%
  ggplot(aes(Var1, value))  
  geom_line(aes(group = 1))  
  geom_point(aes(color = Var1), size = 3)  
  scale_color_brewer(palette = 'Set1', name = NULL)  
  facet_grid(.~Var2, switch = 'x')  
  theme_minimal(base_size = 16)  
  theme(panel.spacing = unit(0, 'mm'),
        strip.placement = 'outside',
        axis.title.x = element_blank())

enter image description here

  • Related