Jellz
Jellz

Reputation: 455

Show multiple legend in ggplot with different data frame

I have a multiple plot with three data frame in ggplot2. I would like to show all three legends.

For example, I have this data set: data('demo')

Group1  Group2  Y   X
A   A1  11.074  -20.0857819
A   A1  11.046  -20.03366372
A   A1  10.927  -19.37661633
A   A1  10.872  -18.72542857
A   A1  11.663  -17.51427049
A   A2  4.608   -13.527
A   A2  4.348   -13.419
A   A2  5.754   -13.434
A   A2  5.617   -12.687
A   A2  5.46    -12.477
A   A3  7.018   -16.91
A   A3  7.41    -11.124
A   A3  3.833   -18.669
A   A3  6.49    -12.424
A   A3  4.892   -20.618
B   B1  7.146   -19.831
B   B1  7.456   -20.128
B   B1  7.562   -19.458
B   B1  8.522   -20.352
B   B1  5.374   -20.457
B   B1  8.755   -19.113
B   B2  9.032   -18.292
B   B2  10.551  -15.258
B   B2  11.276  -15.807
B   B2  10.299  -18.214
B   B2  9.283   -18.358
B   B2  8.872   -17.775
B   B3  9.698   -18.948
B   B3  9.583   -19.007
B   B3  9.356   -18.899
B   B3  9.326   -19.022
B   B3  9.438   -20.599
B   B4  5.111   -19.632
B   B4  2.609   -17.962
B   B4  4.397   -17.973
B   B4  5.079   -17.334
B   B4  4.161   -17.76
C   C1  3.208   -17.13
C   C1  3.546   -16.892
C   C1  3.917   -15.887
C   C1  3.999   -16.274
C   C1  4.592   -15.644
C   C2  10.976  -14.554
C   C2  9.673   -12.923
C   C2  9.274   -10.903
C   C2  9.227   -10.799
C   C2  11.088  -11.222

This is my running code:

#subset data
GroupA <- dplyr::select(filter(demo, Group1=="A"), Group2, X, Y)
GroupB <- dplyr::select(filter(demo, Group1=="B"), Group2, X, Y)
GroupC <- dplyr::select(filter(demo, Group1=="C"), Group2, X, Y)

#summary GroupB
GroupB_YSE <- summarySE(GroupB, measurevar="Y", groupvars=c("Group2"))
GroupB_XSE <- summarySE(GroupB, measurevar="X", groupvars=c("Group2"))

GroupB_SE<-merge(GroupB_YSE, GroupB_XSE, by=c("Group2","N"))

#plot
ggplot(data=GroupB_SE, aes(x=X, y=Y))+
  geom_point(aes(colour=Group2),size=4, alpha=1)+
  geom_errorbar(aes(colour=Group2,ymax=Y+sd.y, ymin=Y-sd.y),alpha=1,size=1.5)+
  geom_errorbarh(aes(colour=Group2,xmax=X+sd.x, xmin=X-sd.x), alpha=1,size=1.5)+
  geom_text(data=GroupB_SE,aes(label=Group2, colour=Group2),check_overlap = F,
        hjust=-0.5, vjust=-0.5, alpha=1, fontface="bold")+

  #GroupB
  geom_point(data=GroupB,aes(color=Group2), size=3, shape=21, alpha=0.2)+
  #GroupA
  geom_point(data=GroupA,aes(shape=Group2), size=2,alpha=0.2)+
  #GroupC
  geom_encircle(data=GroupC, aes(fill = Group2), s_shape = 1, expand = 0,
              alpha = 0.2, color = "black",size=1.5, show.legend = F)+
  geom_point(data=GroupC,aes(colour=Group2),size=2, alpha=0.3, shape= 0)+

  scale_shape_manual(values=2:14)+
  guides(colour = "none", shape = "legend")+

  theme_bw()

This is the output: enter image description here

The question is:

in the current output, the legend only shows factors from GroupA, how can I eide the code to have all legend keys from GroupA, GroupB, GroupC?

Upvotes: 2

Views: 659

Answers (2)

dc37
dc37

Reputation: 16178

When you have multiple dataframe to call, you can use the argument inherit.aes = FALSE in geom_.. in order to indicate to ggplot2 that you are using a different dataframe from the one specified in ggplot(....

So, first, you can summarise your dataframe by grouping by "Group1" and "Group2" using group_by function from dplyr package and calculate the mean and SEM using summarise as follow:

library(dplyr)
Sum_DF <- df %>% group_by(Group1,Group2) %>%
  summarise(Mean_Y = mean(Y),
            Mean_X = mean(X),
            SE_Y = sd(Y)/sqrt(n()),
            SE_X = sd(X)/sqrt(n())) 

# A tibble: 9 x 6
# Groups:   Group1 [3]
  Group1 Group2 Mean_Y Mean_X   SE_Y  SE_X
  <chr>  <chr>   <dbl>  <dbl>  <dbl> <dbl>
1 A      A1      11.1   -19.1 0.142  0.478
2 A      A2       5.16  -13.1 0.284  0.218
3 A      A3       5.93  -15.9 0.677  1.81 
4 B      B1       7.47  -19.9 0.492  0.215
5 B      B2       9.89  -17.3 0.394  0.565
6 B      B3       9.48  -19.3 0.0704 0.327
7 B      B4       4.27  -18.1 0.455  0.392
8 C      C1       3.85  -16.4 0.233  0.285
9 C      C2      10.0   -12.1 0.410  0.728

And then you can use both dataframes (df and Sum_DF) to plot your various geom by calling inherit.aes = FALSE when you want to call the second dataframe (here I used geom_polygon instead of geom_encircle because you did not specify from which library it was obtained - ggalt - and I did not want to install it):

library(ggplot2)
ggplot(df, aes(x = X, y = Y))+
  geom_point(aes(colour = Group2, shape = Group2))+
  geom_polygon(aes(fill = Group2), alpha = 0.2, color = "grey",show.legend = F)+
  geom_point(inherit.aes = FALSE,
             data = Sum_DF, 
             aes(x = Mean_X, y = Mean_Y, colour = Group2), size = 4)+
  geom_errorbar(inherit.aes = FALSE,
                data = Sum_DF, 
                aes(x = Mean_X, ymin = Mean_Y-SE_Y, ymax = Mean_Y+SE_Y,
                    colour = Group2), width = 0.2,show.legend = FALSE)+
  geom_errorbarh(inherit.aes = FALSE, 
                 data = Sum_DF, 
                 aes(y = Mean_Y, xmin = Mean_X-SE_X, xmax = Mean_X+SE_X,
                     colour = Group2), height = 0.2,show.legend = FALSE)+
  geom_text(inherit.aes = FALSE, 
            data= Sum_DF,aes(label=Group2, colour=Group2, x = Mean_X, y = Mean_Y),check_overlap = F,
            hjust=-0.5, vjust=-0.5, alpha=1, fontface="bold", show.legend = FALSE)+
  scale_shape_manual(values = 2:14)+
  guides(colour = "none", shape = "legend")+
  theme_bw()

enter image description here

Upvotes: 3

tjebo
tjebo

Reputation: 23737

Unfortunately, your code is not fully reproducible (where is summarySE from? What are sd.x and sd.y)? Here hopefully some more general guidance, translating Camilles spot on comment into code.

A good procedure for plotting can be:

  • First define an aesthetic for your variables (color/fill/shape/linetype/alpha)
  • Then change the look of this aesthetic with scale functions
  • If need be, you can then adjust the legend, e.g with override.aes
demo <- read.so::read.so('Group1  Group2  Y   X
A   A1  11.074  -20.0857819
                  A   A1  11.046  -20.03366372
                  A   A1  10.927  -19.37661633
                  A   A1  10.872  -18.72542857
                  A   A1  11.663  -17.51427049
                  A   A2  4.608   -13.527
                  A   A2  4.348   -13.419
                  A   A2  5.754   -13.434
                  A   A2  5.617   -12.687
                  A   A2  5.46    -12.477
                  A   A3  7.018   -16.91
                  A   A3  7.41    -11.124
                  A   A3  3.833   -18.669
                  A   A3  6.49    -12.424
                  A   A3  4.892   -20.618
                  B   B1  7.146   -19.831
                  B   B1  7.456   -20.128
                  B   B1  7.562   -19.458
                  B   B1  8.522   -20.352
                  B   B1  5.374   -20.457
                  B   B1  8.755   -19.113
                  B   B2  9.032   -18.292
                  B   B2  10.551  -15.258
                  B   B2  11.276  -15.807
                  B   B2  10.299  -18.214
                  B   B2  9.283   -18.358
                  B   B2  8.872   -17.775
                  B   B3  9.698   -18.948
                  B   B3  9.583   -19.007
                  B   B3  9.356   -18.899
                  B   B3  9.326   -19.022
                  B   B3  9.438   -20.599
                  B   B4  5.111   -19.632
                  B   B4  2.609   -17.962
                  B   B4  4.397   -17.973
                  B   B4  5.079   -17.334
                  B   B4  4.161   -17.76
                  C   C1  3.208   -17.13
                  C   C1  3.546   -16.892
                  C   C1  3.917   -15.887
                  C   C1  3.999   -16.274
                  C   C1  4.592   -15.644
                  C   C2  10.976  -14.554
                  C   C2  9.673   -12.923
                  C   C2  9.274   -10.903
                  C   C2  9.227   -10.799
                  C   C2  11.088  -11.222')

library(ggplot2)
ggplot(demo, aes(x=X, y=Y))+
  geom_point(aes(color= Group2, shape = Group1))+
  scale_shape_manual(values = c(A = 16, B = 0, C = 1)) 

Created on 2020-02-11 by the reprex package (v0.3.0)

Upvotes: 3

Related Questions