2

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?

1
  • 2
    Take a look again at the examples in the ggplot docs and the tutorials they link to. You shouldn't be making calls to the same geom for each group; rather, you should have a variable that you can assign to an encoding such as color. Reshape into long-format data Commented Feb 11, 2020 at 14:24

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

Comments

3

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)

1 Comment

@Dear Tjebo, thank you very much. As my real plot is quite complicated, it not allows me plot as long data format, but has to be in different data frame.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.