Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to replace legend 'bullet' of geom_text guide (legend)

Tags:

r

ggplot2

I would like to replace the 'bullets' in legend (guide) of geom_text. Now it's a tilted a, but I would like a big fat circle or a square or any other shape that will emphasize the color (more).

library(ggplot2)

majdf <- data.frame(lvl = rep(c("A", "B"), each = 50), val = c(rnorm(50, 1), rnorm(50, 3)))
majtxt <- data.frame(species = c("sp1", "sp2", "sp3"), geq = c(0.01, 2, 2.2))

ggplot(majdf, aes(x = val)) +
  geom_density() +
  geom_vline(data = majtxt, aes(xintercept = geq)) +
  geom_text(data = majtxt, aes(x = geq, y = 0.2, label = geq, color = species), angle = 90) +
  facet_wrap(~ lvl)

enter image description here

like image 509
Roman Luštrik Avatar asked Feb 23 '14 17:02

Roman Luštrik


People also ask

How to change the legend label in ggplot?

You can use the following syntax to change the legend labels in ggplot2: p + scale_fill_discrete(labels=c('label1', 'label2', 'label3', ...))

How to remove the legend in ggplot2?

Example 1: Remove All Legends in ggplot2 We simply had to specify legend. position = “none” within the theme options to get rid of both legends.

How do I add a legend to ggplot2?

Adding a legend If you want to add a legend to a ggplot2 chart you will need to pass a categorical (or numerical) variable to color , fill , shape or alpha inside aes . Depending on which argument you use to pass the data and your specific case the output will be different.


2 Answers

This is just a hack.

Create the plot with geom_point:

p1 <- ggplot(majdf, aes(x = val)) +
  geom_density() +
  geom_vline(data = majtxt, aes(xintercept = geq)) +
  geom_point(data = majtxt, aes(x = geq, y = 0.2, label = geq, color = species), angle = 90) +
  facet_wrap(~ lvl)

The same with geom_text:

p2 <- ggplot(majdf, aes(x = val)) +
  geom_density() +
  geom_vline(data = majtxt, aes(xintercept = geq)) +
  geom_text(data = majtxt, aes(x = geq, y = 0.2, label = geq, color = species), angle = 90) +
  facet_wrap(~ lvl)

Turn into a grob and find which element is the guide:

g1 <- ggplotGrob(p1)
g1

TableGrob (8 x 10) "layout": 13 grobs
    z         cells       name                                     grob
1   0 ( 1- 8, 1-10) background          rect[plot.background.rect.2339]
2   1 ( 4- 4, 4- 4)    panel-1                gTree[panel-1.gTree.2263]
3   2 ( 4- 4, 7- 7)    panel-2                gTree[panel-2.gTree.2278]
4   3 ( 3- 3, 4- 4)  strip_t-1    absoluteGrob[strip.absoluteGrob.2306]
5   4 ( 3- 3, 7- 7)  strip_t-2    absoluteGrob[strip.absoluteGrob.2312]
6   5 ( 4- 4, 3- 3)   axis_l-1 absoluteGrob[axis-l-1.absoluteGrob.2299]
7   6 ( 4- 4, 6- 6)   axis_l-2         zeroGrob[axis-l-2.zeroGrob.2300]
8   7 ( 5- 5, 4- 4)   axis_b-1 absoluteGrob[axis-b-1.absoluteGrob.2285]
9   8 ( 5- 5, 7- 7)   axis_b-2 absoluteGrob[axis-b-2.absoluteGrob.2292]
10  9 ( 7- 7, 4- 7)       xlab             text[axis.title.x.text.2314]
11 10 ( 4- 4, 2- 2)       ylab             text[axis.title.y.text.2316]
12 11 ( 4- 4, 9- 9)  guide-box                        gtable[guide-box]
13 12 ( 2- 2, 4- 7)      title               text[plot.title.text.2337]

Copy the guide:

g2 <- ggplotGrob(p2)
g2[[1]][[12]] <- g1[[1]][[12]]
plot(g2)

enter image description here

like image 101
Roland Avatar answered Sep 20 '22 02:09

Roland


ggplot(majdf, aes(x = val)) +
  geom_point(data = majtxt, aes(x = geq, colour = species), 
             y = 0.2, size = 0) +
  geom_density() +
  geom_vline(data = majtxt, aes(xintercept = geq)) +
  geom_text(data = majtxt, aes(x = geq, y = 0.2, label = geq, color = species), 
            angle = 90, show_guide = FALSE) +
  facet_wrap(~ lvl) +
  scale_colour_discrete(guide=guide_legend(override.aes=list(size=4)))

enter image description here

How this works: Add a point geom with the appropriate colour mapping. This will add a point into the legend. But, to keep it from showing up on the the plot, set the size of the point to 0. In the text geom, tell it not to add that part (the rotated a) to the legend (show_guide = FALSE). Finally, the legend will have just the point that you want and not the sideways a; unfortunately, it is drawn at the same size as in the plot, namely 0. So using the override.aes argument to guide_legend (which is passed to guide in scale_colour_discrete), set the size of the point to something "big".

This approach does not require pulling apart pieces to two different plots and stitching them back together.

An alternative way of specifying the guide parameters is using the guides function instead of passing it as an argument to scale_colour_manual:

ggplot(majdf, aes(x = val)) +
  geom_point(data = majtxt, aes(x = geq, colour = species), 
             y = 0.2, size = 0) +
  geom_density() +
  geom_vline(data = majtxt, aes(xintercept = geq)) +
  geom_text(data = majtxt, aes(x = geq, y = 0.2, label = geq, color = species), 
            angle = 90, show_guide = FALSE) +
  facet_wrap(~ lvl) +
  guides(colour = guide_legend(override.aes=list(size=4)))

The resulting graphic is the same.

like image 45
Brian Diggs Avatar answered Sep 21 '22 02:09

Brian Diggs