6
votes

I'm making a scatter plot and I'd like to specify the order of the text in the legend, as well as the colors. Using ggplot, the color order does not match the text order as written.

My Code:

MyX<-c(1,2,3,4,5)
MyY<-c(3,4,5,2,7)
MyCat<-c("Dark","Medium","DarkLight","LightDark","Light")
MyDF<-data.frame(MyX,MyY,MyCat)


ggplot(MyDF, aes(x=MyX, y=MyY, color=MyCat)) +
  geom_point()+
  xlab("Time") + 
  ylab("Num") +
  scale_color_manual(breaks =     c("Dark","DarkLight","Medium","LightDark","Light"),
                     values=c("red", "orange","yellow","cadetblue2","dodgerblue"))

I don't want the default order of the text in the legend, so I'd like to change the order to be:

"Dark","DarkLight","Medium","LightDark","Light"

I also want the colors to be in the gradient:

"red", "orange","yellow","cadetblue2","dodgerblue"

So that Dark = Red, DarkLight = orange, Medium = yellow, LightDark = cadetblue2, Light = blue.

Which is what I would assume would happen with above code. But as plotted the text does not match the color and I have:

Dark = Red, DarkLight = orange, Medium = Blue, LightDark = cadetblue2, Light = yellow.

Note- I have the same issue when using a color ramp:

  gs.pal <- colorRampPalette(c("red","blue"),bias=.1,space="rgb")
+scale_color_manual(breaks = c("Dark","DarkLight","Medium","LightDark","Light"),
                       values=gs.pal(5))
3

3 Answers

6
votes

ggplot is arranging the MyCat variable in alphabetical order in order to avoid that, one needs to define that variable as a factor in the desired order:

library(ggplot2)

MyDF<-data.frame(MyX,MyY,MyCat)

#define as factor in the desired order
MyDF$MyCat<-factor(MyDF$MyCat, levels=c("Dark","DarkLight","Medium","LightDark","Light"))

ggplot(MyDF, aes(x=MyX, y=MyY, color=MyCat)) +
  geom_point()+
  xlab("Time") + 
  ylab("Num") +
  scale_color_manual(breaks = c("Dark","DarkLight","Medium","LightDark","Light"),
                     values=c("red", "orange","yellow","cadetblue2","dodgerblue"))

This should provide the desire order
enter image description here

6
votes

This sets legend names, colors, and order at the same time.

p <- ggplot(dd) + 
      geom_line(aes(x=num_round, y = goods, color = "Good"), size=1) +
      geom_line(aes(x=num_round, y = mediums, color = "Medium"), size=1) + 
      geom_line(aes(x=num_round, y = bads, color = "Bad"), size=1) + 
      scale_color_manual("State", breaks=c("Good", "Medium", "Bad"),
                         values=c("Good"="green","Medium"="orange","Bad"="red")) 
print(p)

enter image description here

2
votes

Dave2e posted an elegant solution; I had a similar problem when comparing two datasets though, where his solution (I think) was less convenient. Another approach might be to use the labels option, whilst making sure that your categories are alphabetical:

MyX<-c(1,2,3,4,5)
MyY<-c(3,4,5,2,7)
MyCat<-c("a","b","c","d","e")
MyDF<-data.frame(MyX,MyY,MyCat)

ggplot(MyDF, aes(x=MyX, y=MyY, color=MyCat)) +
  geom_point()+
  xlab("Time") + 
  ylab("Num") +
  scale_color_manual(breaks = c("a","b","c","d","e"),
                     values= c("red", "orange","yellow","cadetblue2","dodgerblue"),
                    labels= c("Dark","Medium","DarkLight","LightDark","Light"))

Which also works rather straightforwardly you have different datasets:

ggplot(MyDF, aes(x=MyX, y=MyY, color="a")) +
  geom_point()+
  geom_point(data=data.frame(time=c(1,2,3),num=c(4,5,6)),aes(x=time,y=num,color="c"))+
  geom_hline(aes(yintercept=3.5, color="b"))+
  xlab("Time") + 
  ylab("Num") +
  scale_color_manual(breaks = c("a","b","c"),
                     values= c("black", "red","blue"),
                    labels= c("c_black_line","b_red_line","a_blue_line"))