Control point border thickness in ggplot
Asked Answered
K

3

110

When using ggplot, I can set shape to 21-25 to get shapes that have independent setting for the internal (fill) and border (col) colors, like so:

df <- data.frame(id=runif(12), x=1:12, y=runif(12))
ggplot(df, aes(x=x, y=y)) + 
  geom_point(aes(fill=id, size=id), colour="black", shape=21)

enter image description here

However, I can't figure out how to control the thickness of the shape borders, either setting them absolutely or as an aesthetic mapping. I note that if I set an lwd value, it overrides the size aesthetic:

ggplot(df, aes(x=x, y=y)) + 
  geom_point(aes(fill=id, size=id), colour="black", shape=21, lwd=2)

enter image description here

How do I control the border thickness?

Krahling answered 21/10, 2013 at 23:37 Comment(0)
K
155

Starting in version 2.0.0 of ggplot2, there is an argument to control point border thickness. From the NEWS.md file:

geom_point() gains a stroke aesthetic which controls the border width of shapes 21-25 (#1133, @SeySayux). size and stroke are additive so a point with size = 5 and stroke = 5 will have a diameter of 10mm. (#1142)

Thus, the correct solution to this is now:

df <- data.frame(id=runif(12), x=1:12, y=runif(12))
ggplot(df, aes(x=x, y=y)) + 
  geom_point(aes(fill=id, size=id), colour="black", shape=21, stroke = 2)

Output

Krahling answered 18/12, 2015 at 18:23 Comment(5)
Can you add the output?Halfon
For future compatibility and clarity it would be nice to say "Starting in version x.xx" rather than "the latest version".Hydrastinine
Is there a way of controlling the thickness of the stroke based on the variables? Something along the lines of "scale_stroke_manual"?Emplace
As a response to my own comment above, we can use scale_discrete_manual. See link here: github.com/tidyverse/ggplot2/issues/3507#issuecomment-526212978Emplace
Any ideas why stroke=0 still draws it in PDF but not in PNG?Trisyllable
F
19

It feels a bit hacky but you can add a "background" set of dots with the size set to the aesthetic mapping plus some small constant to enlarge the border of the dots. Play with the constant to get the desired border width.

You'll also have to disable the size legend to stop it displaying the legend on the graph...

ggplot(df, aes(x=x, y=y)) + 
  geom_point(aes(size=id+0.5), colour="black" , show_guide = FALSE )+
  scale_size( guide = "none" )+
  geom_point(aes(fill=id, size=id), colour="black", shape=21)

enter image description here

Foah answered 21/10, 2013 at 23:51 Comment(2)
Maybe hackey, but Hadley endorsed this method on TwitterKrahling
@NoamRoss do you have the link for that?Ferriferous
D
1

Another solution is to create the plot in R and then export it to a .svg file. The linewidth can then be changed using vector graphics editing software (e.g., Inkscape). This method is particularly useful when data points overlap.

Decca answered 3/3, 2015 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.