Coloque un borde alrededor de los puntos
Frecuentes
Visto 104,233 veces
63
I'd like to place a black border around points on a scatterplot that are filled based on data, using ggplot2. Also, I would like to avoid having a legend entry for the black border since it will be on each point. Basically I'm looking for this plot, but with a black border around each point.
df <- data.frame(id=runif(12), x=1:12, y=runif(12))
ggplot(df, aes(x=x, y=y))+geom_point(aes(colour=id), size=12)
As a bonus, I'd like to not have a legend entry for the black border. My best try is:
df <- data.frame(id=runif(12), x=1:12, y=runif(12))
ggplot(df, aes(x=x, y=y))+geom_point(aes(fill=id, colour="black"), size=12)
Lo que da:
I don't understand why that doesn't give me what I want, and worse (for my education in ggplot2) I don't understand why it doesn't seem to map fill color to anything! Any help?
Perhaps if I can get the outline and fill mapping right I can use a hack like the one in hte last set of figures aquí to turn off the legend.
5 Respuestas
110
It's a bit obscure, but you have to use pch
>20 (I think 21:25 are the relevant shapes): fill
controls the interior colo(u)ring and colour
controls the line around the edge.
(g0 <- ggplot(df, aes(x=x, y=y))+geom_point(aes(fill=id),
colour="black",pch=21, size=5))
actualización: with recent ggplot2 versions (e.g. 2.0.0, don't know how far back it goes) the default guide is a colourbar. Need g0 + guides(fill="legend")
to get a legend with points as in the plot shown here. The default breaks have changed, too: to exactamente replicate this plot you need g0 + scale_fill_continuous(guide="legend",breaks=seq(0.2,0.8,by=0.1))
...
Relacionado pero no idéntico: ¿Cómo crear una gráfica con puntos personalizados en R? . The accepted answer to that question uses the layering technique shown in @joran's answer, but (IMO) the answer by @jbaums, which uses the pch=21
technique, is superior. (I think shape=21
is an alternative, and perhaps even preferred, to pch=21
.)
PS you should put colour
afuera the mapping (aes
bit) if you want to set it absolutely and not according to the value of some variable ...
contestado el 23 de mayo de 17 a las 13:05
29
The first question's a gimme:
ggplot(df, aes(x=x, y=y)) +
geom_point(aes(colour=id), size=12) +
geom_point(shape = 1,size = 12,colour = "black")
And, oh, you no want an extra legend. I think that does it then:
contestado el 03 de mayo de 12 a las 19:05
Interestingly a guide doesn't show up for the second geom_point - I don't really understand why that is, but since it is what I wanted anyway I'll worry about it another day - dibujó steen
Oh, I see why - because it is not inside an aes() call - dibujó steen
@DrewSteen - looks like you got it, I asked a similar question a while back since it took me a while to figure that out too. I'm not sure if/what would be made out of date by the introduction of ggplot 0.9: stackoverflow.com/questions/4221168/… - persecución
This is nice, but fails if you're using jitter. - Luštrik romano
@Seanosapien sure, just "jitter" the points manually (transform the values in df
) using either rnorm
or jitter
. You may want to store these values in a new variable in case you need raw values downstream. - Luštrik romano
6
I had the same issue, but I needed a solution that allows for jitter, too. For this you do need to use a pch that is a filled shape with a border and a grid.edit function from gridExtra package. Using your example:
df <- data.frame(id=runif(12), x=1:12, y=runif(12))
ggplot(df, aes(x=x, y=y, fill=id))+geom_point(pch=21, colour="Black", size=12)
library(gridExtra)
grid.edit("geom_point.points", grep = TRUE, gp = gpar(lwd = 3))
Respondido 19 Feb 15, 00:02
4
I had the same question, but perhaps since I was using geom_map with latitudes and longitudes, the other answers as of January 2020 didn't work for me.
Restating the question, where the following does not have a black outline around the points:
df <- data.frame(id=runif(12), x=1:12, y=runif(12))
ggplot(df, aes(x=x, y=y))+geom_point(aes(colour=id), size=12)
If I declared both the color and fill in the aesthetic and then used shape 21, problem solved.
ggplot(df, aes(x=x, y=y)) +
geom_point(aes(colour=id, fill=id),
shape = 21,size = 12,colour = "black")
Respondido el 07 de enero de 20 a las 17:01
Hi @windyvation what if my data is plotted so the size depends on a variable, how can I add a black outline to the circles? My plot would be like this ggplot(data, aes(x = Region, y = func, label=NA)) + geom_point(aes(size = scaled_val, colour = value), shape = 21, colour = "black") + geom_text(hjust = 1, size = 2) + theme_bw()+ scale_color_gradient(low = "lightblue", high = "darkblue")
- ecg
@Ecg modifying the code above, the following works for variable size: library(tidyverse) size_x <- 1:12 df <- data.frame(id=runif(12), x=1:12, y=runif(12), size = size_x) ggplot(df, aes(x=x, y=y)) + geom_point(aes(colour=id, fill=id), shape = 21,size = size_x,colour = "black") - windyvation
0
If you want more control (for example, borders on points with various shapes and transparencies), use the fill
aesthetic with shapes 21:25
ggplot(aes(x = Sepal.Length, y = Petal.Width, fill = Species, shape = Species), data = iris) + # notice: fill
geom_point(size = 4, alpha = 0.5) + # transparent point
geom_point(size = 4, fill = NA, colour = "black") + # black border
scale_shape_manual(values = c(21:23)) + # enable fill aesthetic
theme_classic()
Respondido 27 Oct 20, 14:10
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas r ggplot2 or haz tu propia pregunta.
Thanks Ben. Is there any way to change the stroke (outline) width using this method? - geoteoria
I don't see one (I tried setting
width
ylwd
), sorry. - ben bolkerThank you for this - never would have gotten there without this answer! - user2017023