manually - Coincide con el color del texto de la leyenda en geom_text al símbolo
legend.position r (3)
Los colores de la trama son los mismos que los de la leyenda, pero la fuente de la leyenda sigue siendo nítida incluso cuando establece la fuente de la gráfica en negrita (o cursiva). No estoy seguro si esto es un descuido en el diseño de ggplot2
o el comportamiento previsto. Para algunos colores, el tipo de letra en negrita parece más saturado que el tipo de letra normal, lo que le da un aspecto diferente.
En cualquier caso, aquí hay un truco que es mucho más fácil que jugar con grobs, pero eso puede darte lo que quieres. Usa geom_text
con la fuente simple, pero hazlo dos o tres veces seguidas (o más), así obtendrás un sobrerrollado. Esto hará que tanto los símbolos como la leyenda aparezcan de forma similar a la negrita de la fuente, porque ambos estarán sobrerrrollados y los símbolos de la leyenda siempre se verán igual que los símbolos de la gráfica.
Aquí hay un ejemplo:
library(ggplot2)
library(gridExtra)
# Original plot (with larger font size)
p1 <- ggplot(data=df) +
geom_text(aes(x=b, y=a, label=c, color=d), fontface=''bold'', size=8)
p1 <- p1 + scale_color_hue(name="colors should match",breaks=c("one", "two"),
labels=c("should be pink", "should be blue")) +
ggtitle("Original Plot with Bold Symbols and Plain Legend")
# New version with overplotting. (You don''t need to specify ''plain'' fontface.
# I''ve just included that to emphasize what the code is doing.)
p1.overplot <- ggplot(data=df) +
geom_text(aes(x=b, y=a, label=c, color=d), fontface=''plain'', size=8) +
geom_text(aes(x=b, y=a, label=c, color=d), fontface=''plain'', size=8) +
geom_text(aes(x=b, y=a, label=c, color=d), fontface=''plain'', size=8)
p1.overplot <- p1.overplot +
scale_color_hue(name="colors should match",
breaks=c("one", "two"),
labels=c("should be pink", "should be blue")) +
ggtitle("Both symbols and legend are overplotted 3 times")
geom_text
combinar el color del texto de la leyenda con el color del texto producido por una variable factorizada usando geom_text
. Aquí hay un ejemplo de trabajo mínimo:
df <- data.frame(a=rnorm(10),b=1:10,c=letters[1:10],d=c("one","two"))
p1 <-ggplot(data=df,aes(x=b,y=a))
p1 <- p1 + geom_text(aes(label = c, color=d, fontface="bold"))
p1 <- p1 + scale_color_hue(name="colors should match",breaks=c("one", "two"),
labels=c("should be pink", "should be blue"))
p1
Estoy seguro de que es una solución simple. Cualquier sugerencia o referencia a publicaciones anteriores ayudaría. No encontré nada específico para esto.
Siguiendo con el comentario anterior de joran, puedes editar los grobs directamente. Este es un código bastante feo, así que disculpas [habrá una forma mucho más elegante de hacer esto usando comandos de grid
, y con suerte alguien publicará].
library(grid)
gglabcol <-
function(plot1)
{
g <- ggplotGrob(plot1)
# legend grobs
g.b <- g[["grobs"]][[which(g$layout$name=="guide-box")]]
l <- g.b[["grobs"]][[1]][["grobs"]]
# get grobs for legend symbols (extract colour)
lg <- l[sapply(l, function(i) grepl("GRID.text", i))]
# get grobs for legend labels
lb <- l[sapply(l, function(i) grepl("guide.label", i))]
# get change colour of labels to colour of symbols
for(i in seq_along(lg)) {
lb[[i]]$gp$col <- lg[[i]]$gp$col
g.b[["grobs"]][[1]][["grobs"]][sapply(g.b[["grobs"]][[1]][["grobs"]],
function(i) grepl("guide.label", i))][[i]] <- lb[[i]]
}
# overwrite original legend
g[["grobs"]][[which(g$layout$name=="guide-box")]] <- g.b
grid.draw(g)
invisible(g)
}
Trama
gglabcol(p1)
A veces es más fácil editar un grob usando las funciones de edición de la grilla, si se pueden encontrar los nombres de los grobs relevantes. En este caso, se pueden encontrar y la edición es sencilla: cambie el color de la etiqueta de negro a rojo o azul.
library(ggplot2)
library(grid)
df <- data.frame(a=rnorm(10),b=1:10,c=letters[1:10],d=c("one","two"))
p1 <-ggplot(data=df,aes(x=b,y=a))
p1 <- p1 + geom_text(aes(label = c, color=d, fontface="bold"))
p1 <- p1 + scale_color_hue(name="colors should match",breaks=c("one", "two"),
labels=c("should be salmon", "should be sky blue"))
p1
# Get the ggplot grob
g <- ggplotGrob(p1)
# Check out the grobs
grid.ls(grid.force(g))
Mire a través de la lista de grobs. Los grobs que queremos editar se encuentran en la parte inferior de la lista, en el conjunto de campos grobo, con nombres que comienzan con "etiqueta". Hay dos grobs:
label-3-3.4-4-4-4
label-4-3.5-4-5-4
# Get names of ''label'' grobs.
names.grobs <- grid.ls(grid.force(g))$name
labels <- names.grobs[which(grepl("label", names.grobs))]
# Get the colours
# The colours are the same as the colours of the plotted points.
# These are available in the ggplot build data.
gt <- ggplot_build(p1)
colours <- unique(gt$data[[1]][, "colour"])
# Edit the ''label'' grobs - change their colours
# Use the `editGrob` function
for(i in seq_along(labels)) {
g <- editGrob(grid.force(g), gPath(labels[i]), grep = TRUE,
gp = gpar(col = colours[i]))
}
# Draw it
grid.newpage()
grid.draw(g)
¿Qué pasa si se requiere que las claves sean puntos en lugar de letras? Podría ser útil porque la ''a'' es un símbolo en la trama, y es un símbolo en la clave de la leyenda. Esta no es una edición simple, como la anterior. Necesito un punto grob para tomar el lugar del texto grob. Dibujo tablas en ventanas gráficas, pero si puedo encontrar los nombres de las ventanas gráficas relevantes, debería ser sencillo realizar el cambio.
# Find the names of the relevant viewports
current.vpTree() # Scroll out to the right to find he relevant ''key'' viewports.
ventana [clave-4-1-1.5-2-5-2], ventana gráfica [clave-3-1-1.4-2-4-2],
# Well, this is convenient. The names of the viewports are the same
# as the names of the grobs (see above).
# Easy enough to get the names from the ''names.grobs'' list (see above).
# Get the names of ''key'' viewports(/grobs)
keys <- names.grobs[which(grepl("key-[0-9]-1-1", names.grobs))]
# Insert points grobs into the viewports:
# Push to the viewport;
# Insert the point grob;
# Pop the viewport.
for(i in seq_along(keys)) {
downViewport(keys[i])
grid.points(x = .5, y = .5, pch = 16, gp = gpar(col = colours[i]))
popViewport()
}
popViewport(0)
# I''m not going to worry about removing the text grobs.
# The point grobs are large enough to hide them.
plot = grid.grab()
grid.newpage()
grid.draw(plot)
Actualizar
Teniendo en cuenta los consejos de @ user20650 para cambiar la clave de leyenda (ver el comentario a continuación):
p1 <-ggplot(data=df,aes(x=b,y=a))
p1 <- p1 + geom_text(aes(label = c, color=d, fontface="bold"))
p1 <- p1 + scale_color_hue(name="colors should match",breaks=c("one", "two"),
labels=c("should be salmon", "should be sky blue"))
GeomText$draw_key <- function (data, params, size) {
pointsGrob(0.5, 0.5, pch = 16,
gp = gpar(col = alpha(data$colour, data$alpha),
fontsize = data$size * .pt)) }
p1
Luego, proceda como antes para cambiar el color del texto de la leyenda.