4

I am quite new to ggplot2 and it's been challenging to reproduce a similar chart in Excel. I almost got it to work, but now I need to figure out a way to make the geom_point/line's legend key (3rd item in the legend) to not show the box around it.

Note: I know there are answers to similar problem by using + theme(legend.key = element_blank()), but it has no effect on the legend. I suspect it has something to do with the scale_*_manual in the code. Any other solutions would be truly appreciated!

test <- data.frame(
  group      = 1:5,
  cnt        = rep(600, 5),
  pct_cnt    = rep(0.2, 5),
  prem       = c(12000000, 9800000, 8700000, 11000000, 3500000),
  pct_prem   = c(0.266666667, 0.217777778, 0.193333333, 0.244444444, 
                 0.077777778),
  relativity = c(1.5, 1.2, 1, 0.8, 0.4)
)

theme_set(theme_minimal())
normalizer <- round(max(test$relativity) / max(test$pct_prem), 0)

ggplot(test, aes(x = group)) + 
  geom_bar(aes(y = pct_prem, fill = 'prem', color = 'prem'), stat = 'identity', position = position_nudge(x = -0.1), width = 0.2) +
  geom_bar(aes(y = pct_cnt, fill = 'cnt', color = 'cnt'), stat = 'identity', position = position_nudge(x = 0.1), width = 0.2) +
  geom_point(aes(y = relativity / normalizer, color = 'rel', fill = 'rel'), size = 5) +
  geom_line(aes(y = relativity / normalizer, color = 'rel'), size = 2) +
  scale_color_manual(name = 'metric', values = c('prem' = NA, 'cnt' = NA, 'rel' = 'skyblue'),
                     labels = c('prem' = '%Prem', 'cnt' = '%Count', 'rel' = 'LRR')) +
  scale_fill_manual(name = 'metric', values = c('prem' = 'orange', 'cnt' = 'dark green', 'rel' = NA),
                    labels = c('prem' = '%Prem', 'cnt' = '%Count', 'rel' = 'LRR')) +
  scale_y_continuous(limits = c(0, 0.4), sec.axis = sec_axis(~.*normalizer, breaks = seq(0, 0.4, 0.1) * normalizer, name = 'relativity'))

ggplot2 version
Excel chart

EKtheSage
  • 199
  • 6

2 Answers2

7

I'm not sure if there is a method using just ggplot, since the color of the box and the color of your legend key itself change simultaneously when using the common override.aes fix. Going into the gtable, you could do it this way (after assigning your plot to p):

library(grid)
grb <- ggplotGrob(p)
#get the index of the legend-grob and store grob as leg
leg_index <- grep("guide-box", sapply(grb$grobs, function(x) x$name))
leg <- grb$grobs[[leg_index]]

Then, you want to look in the legend's gtable. The key bg to be changed is the last one, so check at the bottom for rect backgrounds. I.e., here

13 13 (6-6,2-2) key-5-1-bg        zeroGrob[legend.key..zeroGrob.3081]
14 14 (6-6,2-2)  key-5-1-1                       rect[GRID.rect.3082]
15 15 (6-6,2-2)  key-5-1-2                       rect[GRID.rect.3083]
16 16 (6-6,2-2)  key-5-1-3                   points[GRID.points.3084]
17 17 (6-6,2-2)  key-5-1-4               segments[GRID.segments.3085]

Indices 14 and 15 are the ones belonging to the last key. To make sure the bg is removed, just change the graphic parameters of both of them. Then replace the old legend with your changed one.

leg$grobs[[1]]$grobs[[14]]$gp$col <- "white"
leg$grobs[[1]]$grobs[[15]]$gp$col <- "white"
grb$grobs[[leg_index]] <- leg


grid.newpage()
grid.draw(grb)

enter image description here

erocoar
  • 5,723
  • 3
  • 23
  • 45
0

To move a legend on the bottom of the graph you add "bottom" to legend.position like this....

 theme(legend.position="bottom")

enter image description here

here is your original code adjusted..

ggplot(test, aes(x = group)) + 
  geom_bar(aes(y = pct_prem, fill = 'prem', color = 'prem'), stat = 'identity', position = position_nudge(x = -0.1), width = 0.2, alpha = 1) +
  geom_bar(aes(y = pct_cnt, fill = 'cnt', color = 'cnt'), stat = 'identity', position = position_nudge(x = 0.1), width = 0.2) +
  geom_point(aes(y = relativity / normalizer, color = 'rel', fill = 'rel'), size = 5) +
  geom_line(aes(y = relativity / normalizer, color = 'rel'), size = 2) +
  scale_color_manual(name = 'metric', values = c('prem' = NA, 'cnt' = NA, 'rel' = 'skyblue'),
                     labels = c('prem' = '%Prem', 'cnt' = '%Count', 'rel' = 'LRR')) +
  scale_fill_manual(name = 'metric', values = c('prem' = 'orange', 'cnt' = 'dark green', 'rel' = NA),
                    labels = c('prem' = '%Prem', 'cnt' = '%Count', 'rel' = 'LRR')) +
  scale_y_continuous(limits = c(0, 0.4) , sec.axis = sec_axis(~.*normalizer, breaks = seq(0, 0.4, 0.1) * normalizer, name = 'relativity'))+
  theme(legend.position="bottom")

For further adjustments that can be made look up theme (tons of options)

?theme

Hope this helps!

Michael Cantrall
  • 313
  • 3
  • 15
  • Sorry my question wasn't clear. I wanted to make the 3rd item in the legend key (LRR) to have no box around it. I have tried `legend.key = element_blank())` but it wasn't working. – EKtheSage Mar 04 '18 at 18:42
  • oh, your looking to have the box around the LRR removed? – Michael Cantrall Mar 04 '18 at 18:54