0
votes

I want to put black boxes around the alpha values in the legend, so the smallest value (70) actually shows up. To be clear: around each individual square representing each alpha value, not around the whole legend.

mtcars
test_plot <- ggplot() +
  geom_point(data = mtcars, 
             aes(x = wt, y = mpg,
                 alpha = disp,
                 size = hp), 
             fill = 'black',
             shape = 21) + 
  geom_point(data = mtcars, 
             aes(x = cyl, y = mpg,
                 size = hp), 
             fill = 'black',
             shape = 1) +
  xlab("Weight") + ylab("MPG") + 
  labs(size = "Horsepower:", alpha = "Displacement:") +
  scale_size_continuous(range = c(1,10), breaks= c(50, 100, 150, 200, 250, 300, 350)) +
  scale_alpha_continuous(range = c(0,1), 
                         breaks= c(71.1, 100, 200, 300, 400, 500), 
                         labels = c(70, 100, 200, 300, 400, 500)) +
  guides(size = guide_legend(override.aes = list(shape = 1)),
         alpha = guide_legend(override.aes = list(shape = 22, color = 'black')))

test_plot

Example of the plot

2

2 Answers

0
votes

The issue is that the alpha value is both applied to the fill of the legend key and the border color. Unfortunately I'm not aware of an easy solution to this. One approach to get your desired result is by manipulating the gtable.

library(ggplot2)

p <- ggplot() +
  geom_point(data = mtcars, 
             aes(x = wt, y = mpg,
                 alpha = disp,
                 size = hp), 
             fill = 'black',
             shape = 21) + 
  geom_point(data = mtcars, 
             aes(x = cyl, y = mpg,
                 size = hp), 
             fill = 'black',
             shape = 1) +
  xlab("Weight") + ylab("MPG") + 
  labs(size = "Horsepower:", alpha = "Displacement:") +
  scale_size_continuous(range = c(1,10), breaks= c(50, 100, 150, 200, 250, 300, 350)) +
  scale_alpha_continuous(range = c(0,1), 
                         breaks= c(71.1, 100, 200, 300, 400, 500), 
                         labels = c(70, 100, 200, 300, 400, 500)) +
  guides(size = guide_legend(override.aes = list(shape = 1)),
         alpha = guide_legend(override.aes = list(shape = 22, color = 'black')))

library(gtable)
library(grid)

g <- ggplotGrob(p)
for (i in c(4, 6, 8, 10, 12)) { # Indices of legend keys
  # guide-box is element 15 in the gtable
  # alpha legend if the first element of the "guide-box"
  gp <- g$grobs[[15]]$grobs[[1]]$grobs[[i]]$gp
  gp <- modifyList(gp, list(col = "black"))
  
  g$grobs[[15]]$grobs[[1]]$grobs[[i]]$gp <- do.call(grid::gpar, gp)
}
grid.newpage()
grid.draw(g)

0
votes

Map the variable to fill instead of alpha, with some shape that has an edge, and use scale_fill_gradient* with colors varying in alpha. Use stroke to control the size of the border.

I simplified your example to highlight the relevant points of the code:

ggplot(mtcars, aes(wt, mpg)) +
  geom_point(aes(fill = disp), shape = 21, size = 10, stroke = 1e-10) +
  scale_fill_gradient(low = alpha("black", 0), high = alpha("black", 1),  guide = "legend") +
  guides(fill = guide_legend(override.aes = list(size = 6, stroke = .5)))

enter image description here