1

Here's a silly data.frame:

df <- read.table(textConnection( "pole medal bag x y north gold paper 0.852 0.423 north gold plastic 0.277 0.055 north silver paper 0.257 0.211 north silver plastic 0.457 0.614 north bronze paper 0.825 0.299 north bronze plastic 0.672 0.126 south gold paper 0.482 0.764 south gold plastic 0.603 0.869 south silver paper 0.327 0.451 south silver plastic 0.147 0.672 south bronze paper 0.140 0.466 south bronze plastic 0.833 0.325 "), header = TRUE) 

I know how to plot a scatterplot for these data in a way that uses color and shape to indicate two of the factor attributes; for example:

library(ggplot2) ggplot(data = df, aes(x = x, y = y)) + geom_point(size = 4, aes(shape = pole, color = bag)) 

enter image description here

I would like to add one more point feature to indicate a third factor attribute (in this case medal). The one possibility that comes to mind is a colored outline.

Is there a convenient way to do this? (One tricky aspect of the problem is that the color palette for the outlines must be distinct from that used for the point fills, because, for each point, the outline and the fill must be visually distinguishable.)

UPDATE:

When I try Gregor's suggestion, the points look right, but the legend is messed up:

enter image description here

7
  • 1
    You will likely need to establish your own color schemes for the fill vs color to make this look OK. Plus some legend work. Such as: scale_fill_manual(values = c("pink", "white")) + scale_color_manual(values = c("brown", "gold", "grey74")) + guides(fill = guide_legend(override.aes = list(color = c("pink", "white"))), color = guide_legend(override.aes = list(shape = 21))) Commented Aug 17, 2016 at 16:58
  • Why was this question downvoted? Commented Aug 17, 2016 at 17:13
  • @kjo, probably because this is discussed at some length in the docs of geom_point. Also see for example here and Commented Aug 17, 2016 at 19:14
  • The discussion in the examples here says: "For shapes that have a border (like 21), you can colour the inside and outside separately. Use the stroke aesthetic to modify the width of the border" Commented Aug 18, 2016 at 15:00
  • 1
    @Axeman: OK, we differ in what we consider to be "discussed at some length". The necessary scale_* and guide modifications given by aosmith and Gregor are not explicitly mentioned in the docs. Those are all part of the answer I was looking for. But, hey, that's OK: it's not the first time that a question of mine gets downvoted by someone who did not bother to understand the question in the first place. Commented Aug 18, 2016 at 15:37

1 Answer 1

8

Yes you can! There is an example in the help for ?geom_point:

# For shapes that have a border (like 21), you can colour the inside and # outside separately. Use the stroke aesthetic to modify the width of the # border ggplot(mtcars, aes(wt, mpg)) + geom_point(shape = 21, colour = "black", fill = "white", size = 5, stroke = 5) 

In your case you'll want to use shapes 21 (circles with outline) and 24 (triangles with outline) like this:

ggplot(data = df, aes(x = x, y = y)) + geom_point(aes(shape = pole, color = medal, fill = bag), size = 4, stroke = 2) + scale_shape_manual(values = c(21, 24)) 

Notice that, when using both, fill corresponds to the center of the points and color to the outline. You can change the weight of the outline by setting stroke.

As noted in the comments, you'll have to do some extra tweaking to get the legend right. Adding to the above plot:

fill_col = c("pink", "white") outline_col = c("brown", "gold", "grey74") scale_fill_manual(values = fill_col) + scale_color_manual(values = outline_col) + guides(fill = guide_legend(override.aes = list(color = fill_col)), color = guide_legend(override.aes = list(shape = 21))) 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.