Keep ordering of my data in ggplot legend where co

2019-04-11 00:23发布

问题:

I am creating a plot where I need to mix names, colors and shapes in a single legend. It seems the legend order my data alphabetically by className generating a mismatch with my class shapes and colors... I need to have unique shape per superclasses A, B, C so I expected to have A1, A2, A3 as triangles, and B1, B2 as circles. How can I force the legend names to follows the same order as colors and shapes as in my data? (I don't want alphabetical order in the legend which makes no sense for my real application)

Here my data and code:

library(ggplot2)
x<-c(1,2,3,4,5,6,7,8,9)
y<-c(1,1,2,2,2,3,3,3,3)
classNames<-c("B1","B2","A1","A2","A3","C1","C2","C3","C4")
classColors<-c("darkorange","darkorange3","cyan","blue","blue4","green1","green2","green3","green4")
classShapes<-c(1,1,2,2,2,3,3,3,3)

datadf<-data.frame(x,y,classNames,stringsAsFactors = FALSE)

ggplot()+
  geom_point(data=datadf,aes(x=x,y=y,shape=classNames,color=classNames))+
  scale_color_manual(name="My classes",values=classColors)+
  scale_shape_manual(name="My classes",values=classShapes)

Names in legend are ordered alphabetically not matching the order I specified in my data, so not matching my colors and shapes, and causing problem as I really need my legend items follows the same order as in my data.

If I use this ggplot instead, names matches with shapes and color and come in good order in the legend, but now they do not match with points in the plot...

ggplot()+
  geom_point(data=datadf,aes(x=x,y=y,shape=classNames,color=classNames))+
  scale_color_manual(name="My classes",values=classColors,labels=classNames) +
  scale_shape_manual(name="My classes",values=classShapes,labels=classNames)

Now names in legend match shapes and colors as in my data, but now mismatch is in the plot x,y positions.

回答1:

The order of the legend items depends on the level order in the factor variable defining the legend.

library(ggplot2)
    x<-c(1,2,3,4,5,6,7,8,9)
    y<-c(1,1,2,2,2,3,3,3,3)
    classNames<-c("B1","B2","A1","A2","A3","C1","C2","C3","C4")
    classColors<-c("darkorange","darkorange3","cyan","blue","blue4","green1","green2","green3","green4")
    classShapes<-c(1,1,2,2,2,3,3,3,3)

datadf<-data.frame(x,y,classNames,stringsAsFactors = FALSE)
#defining the levels:
datadf$classNames <- factor(datadf$classNames, levels = classNames)


ggplot()+
  geom_point(data=datadf,aes(x=x,y=y,shape=classNames,color=classNames))+
  scale_color_manual(name="My classes",values = classColors)+
  scale_shape_manual(name="My classes",values = classShapes)

another approach is defining the coloring manually:

ggplot()+
  geom_point(data=datadf,aes(x=x,y=y,shape=classNames,color=classNames))+
  scale_color_manual(name="My classes",values = c("A1" = "blue", "A2" = "red", "A3" = "orange", "B1" = "brown", "B2" = "black", "C1" = "grey50", "C2" = "pink", "C3" = "lightblue", "C4" = "green"))+
  scale_shape_manual(name="My classes",values= c("A1" = 1, "A2" = 2, "A3" = 3, "B1" = 4, "B2" = 5, "C1" = 6, "C2" = 7, "C3" = 8, "C4" = 9))



标签: r ggplot2 legend