Coloque un borde alrededor de los puntos

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)

the plot I want, except it doesn't have borders around the points

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:

not at all the plot I want

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.

preguntado el 03 de mayo de 12 a las 19:05

5 Respuestas

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)) ...

enter image description here

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

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 y lwd), sorry. - ben bolker

Thank you for this - never would have gotten there without this answer! - user2017023

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:

enter image description here

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:… - 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

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)

grid.edit("geom_point.points", grep = TRUE, gp = gpar(lwd = 3))

Respondido 19 Feb 15, 00:02

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")

Points Outlined in 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

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

Respondido 27 Oct 20, 14:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.