Adding a Legend to an Existing ggplot

I have been trying to figure out how to add a legend on the right side of my ggplot (that @andresrcs originally helped me with) to show five different symbols and the corresponding symbols' meaning.
Legend Title can be as simple as "Prices". I've tried many different ways and all have failed. I guess I'm needing help from the experts.

(I am unsure how to make the graph appear that my code creates)

Variables needing to be placed in a legend:

-Price (black circle scatter points)
-Average Price (red circle, the average calculated from the scatter plot prices of variable "Price")
-Price.A (blue triangle or pch 24)
-Price.B (green square or pch 22)
-Price.C (purple star or pch 8)

Product.Code <- c("F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162")
Product.Name <- c("blah", "blah", "blah", "blah", "blah", "blah", "blah", "blah", "blah", "blah")
Price        <- c(2.5,
                  4,
                  2.5,
                  2.71,
                  1.89,
                  2,
                  2.62,
                  2.89,
                  1.98,
                  1.72
)

Price.A     <- c(2.3,
                 2.3,
                 2.3,
                 2.3,
                 2.3,
                 2.3,
                 2.3,
                 2.3,
                 2.3,
                 2.3
)

Price.B      <- c(2.1,
                  2.1,
                  2.1,
                  2.1,
                  2.1,
                  2.1,
                  2.1,
                  2.1,
                  2.1,
                  2.1
)

Price.C      <- c(1.25,
                  1.25,
                  1.25,
                  1.25,
                  1.25,
                  1.25,
                  1.25,
                  1.25,
                  1.25,
                  1.25
)

df <- data.frame(Product.Code, Product.Name, Price, Price.A, Price.B, Price.C)
attach(df)

ggplot(df, aes(x = "", y = Price)) + 
  geom_boxplot(fill = 'mistyrose') +
  stat_summary(fun.y=mean, geom = "point", shape = 20, size = 7, color = "red", fill = "red") +
  geom_point(position = 'jitter') + 
  coord_flip() +
  labs(x = "") +
  labs(title = df$Product.Name) +
  labs(subtitle = df$Product.Code) +
  geom_point(data = df, mapping=aes(x = "", y = Price.A, pch = 24),  
             size = 3, color = "blue", fill = "blue") +
  geom_point(data = df, mapping=aes(x = "", y = Price.B, pch = 22),  
             size = 3, color = "green", fill = "green") +
  geom_point(data = df, mapping=aes(x = "", y = Price.C, pch = 8),  
             size = 3, color = "purple", fill = "purple") +
  scale_shape_identity() 

If you use the reprex package, the chart will automatically be included on the clipboard.

install.packages("reprex")

If you've never heard of a reprex before, you might want to start by reading the tidyverse.org help page. The reprex dos and don'ts are also useful.

What to do if you run into clipboard problems

If you run into problems with access to your clipboard, you can specify an outfile for the reprex, and then copy and paste the contents into the forum.

reprex::reprex(input = "fruits_stringdist.R", outfile = "fruits_stringdist.md")

For pointers specific to the community site, check out the reprex FAQ.

1 Like

You can do something like this example, and following the same logic you can even include the shape in your legend.

library(ggplot2)
df <- data.frame(
    Price = c(2.5, 4, 2.5, 2.71, 1.89, 2, 2.62, 2.89, 1.98, 1.72),
    Price.A = c(2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3),
    Price.B = c(2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1),
    Price.C = c(1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25),
    Product.Code = as.factor(c("F2162", "F2162", "F2162", "F2162", "F2162",
                               "F2162", "F2162", "F2162", "F2162", "F2162")),
    Product.Name = as.factor(c("blah", "blah", "blah", "blah", "blah", "blah",
                               "blah", "blah", "blah", "blah"))
)

ggplot(df, aes(x = "", y = Price)) + 
    geom_boxplot(fill = 'mistyrose') +
    stat_summary(aes(color = "red"), fun.y=mean, geom = "point", shape = 20, size = 7, fill = "red") +
    geom_point(position = 'jitter') + 
    coord_flip() +
    labs(title = df$Product.Name,
         subtitle = df$Product.Code,
         x = "",
         color = "Legend:") +
    geom_point(data = df, mapping=aes(x = "", y = Price.A, pch = 24, color = "blue"),  
               size = 3, fill = "blue") +
    geom_point(data = df, mapping=aes(x = "", y = Price.B, pch = 22, color = "green"),  
               size = 3, fill = "green") +
    geom_point(data = df, mapping=aes(x = "", y = Price.C, pch = 8, color = "purple"),  
               size = 3, fill = "purple") +
    scale_color_manual(values = c("blue", "green", "purple", "red"),
                       labels = c("Price.A", "Price.B", "Price.C", "Mean")) +
    scale_shape_identity()

Created on 2019-02-20 by the reprex package (v0.2.1)

Hi @mara
Thank you. I went ahead and looked at a video on youtube and now it makes sense but I run into this error when I go to run reprex:

Error in file(con, "w") : cannot open the connection
In addition: Warning message:
In file(con, "w") :
cannot open file 'C:/Users/MY NAME.R': Permission denied

Bummer.

@andresrcs Thank you! I am currently attempting to work your suggested code out in my data/code. Will check back later.

@andresrcs and fellow R party people:

I have rearranged my code to reflect @andresrcs suggestions. When trying to match up the shapes on the graph and the shapes on the legend, I ran into the problem of not being able to use the shape command more than once. I get this error because of using scale shape twice: "Scale for 'shape' is already present. Adding another scale for 'shape', which will replace existing scale."
Without the "scale_shape_identity()" I get an error saying, "Error: Continuous value supplied to discrete scale."

I think that my work permissions are getting in the way of using reprex. In the meantime I have attached a picture of the graph produced. Also, below is the code that is giving me problems when using scale shape twice.

library(tidyverse)
library(dplyr)
Product.Code <- c("F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162", "F2162")
Product.Name <- c("blah", "blah", "blah", "blah", "blah", "blah", "blah", "blah", "blah", "blah")
Price        <- c(2.5, 4, 2.5, 2.71, 1.89, 2, 2.62, 2.89, 1.98, 1.72)

Price.A     <- c(2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3)
Price.B      <- c(2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1)
Price.C      <- c(1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25)
Product.Code = as.factor(c("F2162", "F2162", "F2162", "F2162", "F2162",
                           "F2162", "F2162", "F2162", "F2162", "F2162"))
Product.Name = as.factor(c("blah", "blah", "blah", "blah", "blah", "blah",
                           "blah", "blah", "blah", "blah"))

df <- data.frame(Product.Code, Product.Name, Price, Price.A, Price.B, Price.C)
attach(df)

ggplot(df, aes(x = "", y = Price)) + 
  geom_boxplot(fill = 'mistyrose') +
  stat_summary(aes(color = "red"), fun.y=mean, geom = "point", shape = 20, size = 7, fill = "red") +
  geom_point(position = 'jitter') + 
  coord_flip() +
  labs(title = df$Product.Name,
       subtitle = df$Product.Code,
       x = "",
       color = "Legend:") +
  geom_point(data = df, mapping=aes(x = "", y = Price.A, pch = 24, color = "blue"),  
             size = 3, fill = "blue") +
  geom_point(data = df, mapping=aes(x = "", y = Price.B, pch = 22, color = "green"),  
             size = 3, fill = "green") +
  geom_point(data = df, mapping=aes(x = "", y = Price.C, pch = 8, color = "purple"),  
             size = 3, fill = "purple") +
  scale_color_manual(values = c("blue", "green", "purple", "red"),
                     labels = c("Price.A", "Price.B", "Price.C", "Mean")) +
  scale_shape_manual(values = c(24, 22, 8, 20),
                     labels = c("Price.A", "Price.B", "Price.C", "Mean")) +
  scale_shape_identity()

Could this be part of my problem?

scale_shape maps discrete variables to six easily discernible shapes. If you have more than six levels, you will get a warning message, and the seventh and subsequence levels will not appear on the plot. Use scale_shape_manual() to supply your own values. You can not map a continuous variable to shape.

You have to use a named vector for the shape scale

library(ggplot2)
df <- data.frame(
    Price = c(2.5, 4, 2.5, 2.71, 1.89, 2, 2.62, 2.89, 1.98, 1.72),
    Price.A = c(2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3, 2.3),
    Price.B = c(2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1, 2.1),
    Price.C = c(1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25),
    Product.Code = as.factor(c("F2162", "F2162", "F2162", "F2162", "F2162",
                               "F2162", "F2162", "F2162", "F2162", "F2162")),
    Product.Name = as.factor(c("blah", "blah", "blah", "blah", "blah", "blah",
                               "blah", "blah", "blah", "blah"))
)

ggplot(df, aes(x = "", y = Price)) + 
    geom_boxplot(fill = 'mistyrose') +
    stat_summary(aes(color = "red", fill = "red", shape = "Mean"), fun.y=mean, geom = "point", size = 7) +
    geom_point(position = 'jitter') + 
    coord_flip() +
    labs(title = df$Product.Name,
         subtitle = df$Product.Code,
         x = "",
         color = "Legend:",
         shape = "Legend:",
         fill = "Legend:") +
    geom_point(data = df, mapping=aes(x = "", y = Price.A, shape = "A", color = "blue", fill = "blue"),  
               size = 3) +
    geom_point(data = df, mapping=aes(x = "", y = Price.B, shape = "B", color = "green", fill = "green"),  
               size = 3) +
    geom_point(data = df, mapping=aes(x = "", y = Price.C, shape = "C", color = "purple", fill = "purple"),  
               size = 3) +
    scale_color_manual(name="Legend:",
                       values = c("blue", "green", "purple", "red"),
                       labels = c("Price.A", "Price.B", "Price.C", "Mean")) +
    scale_shape_manual(name="Legend:",
                       values = c("A" = 24, "B" = 22, "C" = 8, "Mean" = 20),
                       labels = c("Price.A", "Price.B", "Price.C", "Mean")) +
    scale_fill_manual(name="Legend:",
                      values = c("blue", "green", "purple", "red"),
                      labels = c("Price.A", "Price.B", "Price.C", "Mean"))

3 Likes

@andresrcs Its beautiful!! Thank you so much! I don't think I would have been able to figure this out at the rate I was going digging around for clues on the internet. :grin:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.