Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep ordering of my data in ggplot legend where color and shape are combined

Tags:

r

legend

ggplot2

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.

like image 856
Mica Avatar asked Oct 27 '25 06:10

Mica


1 Answers

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)

enter image description here

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))

enter image description here

like image 158
missuse Avatar answered Oct 28 '25 20:10

missuse



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!