RE: Combining legend colour and shape using values from data frame

3,850 views
Skip to first unread message

Ito, Kaori (Groton)

unread,
Apr 4, 2013, 4:25:41 PM4/4/13
to RyanR, ggp...@googlegroups.com

Dear Ryan,

You cannot merge the legend if you are using continuous and discrete variables.

I think you need create discrete values (if you want to use shape) and account for the  combination of two variables, if you want to have only one legend in the plot…….  

 

mydata.n$group <- interaction(mydata.n$shape,mydata.n$colour)

a <- ggplot(data=mydata.n, aes(x = x, y = y, shape=group, colour=group))

a + geom_point()

 

--Kaori

From: ggp...@googlegroups.com [mailto:ggp...@googlegroups.com] On Behalf Of RyanR
Sent: Thursday, April 04, 2013 1:34 PM
To: ggp...@googlegroups.com
Subject: Combining legend colour and shape using values from data frame

 

Hello all,

I am having some trouble getting a plot legend together.

In my dataframe I have added a column with the shape and colour I would like to use for plotting. When I use these values I am unable to figure out how to combine them in my legend. I have two examples of what I want to do.

1) This is a simple plot where I just use the colour and shape for the symbols.

2) This is slightly more complicated as I add in scaling from a third variable.

What I would like to do is combine the colour and shape into the legend for a single entry.

Here is what I use:

#START
library(ggplot2)  
mydata = read.csv("example.csv")  # file available at https://www.dropbox.com/s/lw5ophv98vdizpu/example.csv
mydata.n<-mydata
mydata.n[,c(4:6)]<-sapply(mydata.n[,c(4:6)],as.numeric)
 
#Plot 1
a <- ggplot(data=mydata.n, aes(x = x, y = y, shape=shape, colour=colour))
a + geom_point() + scale_shape_identity(guide="legend") + scale_colour_identity(guide="legend")
 
#Plot 2
b <- ggplot(data=mydata.n, aes(x = x, y = y, shape=shape, colour=colour, size=z))
b + geom_point() + scale_shape_identity(guide="legend") + scale_colour_identity(guide="legend")
#STOP

Thanks for any help,

-Ryan

--
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2
 
---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Dennis Murphy

unread,
Apr 4, 2013, 10:27:00 PM4/4/13
to RyanR, ggplot2
You can merge legends in a ggplot when :
(a) they have the same legend title;
(b) they have the same breaks;
(c) they have the same labels.
As you've constructed it, none of those requirements are met (through
no real fault of your own - this is not obvious except perhaps in
retrospect). The biggest problem is that colour has four distinct
values and shape has two (with no symmetry),

Reading deeply between the lines, my guess is that you want the legend
labels to be the values of the series variable. If so, here is my stab
at it:

# In this situation, it's better not to have factors in the data -
# they only get in the way
mydata <- read.csv("example.csv", header = TRUE,
stringsAsFactors = FALSE)

# I'm defining shape as a factor in the call below, but it will be
# mutated by specializing its scale:
a <- ggplot(data=mydata, aes(x = x, y = y, shape = factor(series),
colour=colour))

a + geom_point() +
theme_bw() + # Optional: I just liked it better
labs(colour = "Series", shape = "Series") + # same titles
scale_colour_identity(breaks = unique(mydata$colour),
labels = unique(mydata$series),
guide = "legend") +
scale_shape_manual(breaks = levels(factor(mydata$series)),
values = c(18, 15, 18, 18))

The real surgery is in constructing the merged legend. Although the
breaks are 'different' in the two scales, the mapping is 1-1 between
them. The resolution comes with the common labels. I can use the
identity scale for color, but the problem with doing the same for
shape is twofold: (i) there are only two unique values; (ii) you need
the numeric values to pick the right shapes, but
scale_shape_identity() won't accept them because they are numeric
(scale_shape is a discrete scale). We get around it by using
scale_shape_manual() and finagling the values, which are allowed to be
a numeric vector in this function.

Dennis

RyanR

unread,
Apr 5, 2013, 12:43:17 PM4/5/13
to ggp...@googlegroups.com, RyanR
Thank you so much for taking your time to provide this solution. I have a follow up question. When I switch over to my large data set it started producing two different legends. I noticed that unique(mydata$series) and levels(factor(mydata$series)) produced the list of series in a different order (this was not a problem on the small data set).

I worked around this by by using another unique() call instead of the levels(factor()) call in the scale_shape_manual. Are there potential problems to using this as a solution?

b + geom_point() +

    theme_bw() +    # Optional: I just liked it better
    labs(colour = "Series", shape = "Series") +   # same titles
    scale_colour_identity(breaks = unique(mydata$colour),
                                    labels = unique(mydata$series),
                                    guide = "legend") +
    scale_shape_manual(breaks = unique(mydata$series),

                                    values = c(18, 15, 18, 18))

Reply all
Reply to author
Forward
0 new messages