更改 ggplot2 中的图例以具有相似标签组
changing the legends in ggplot2 to have groups of similar labels
此问题基于
中提供的解决方案
如下
library(ggplot2)
library(gtable)
library(grid)
diamonds$cut = factor(diamonds$cut, levels=c("Fair","Good"," ","Very Good",
"Premium","Ideal"))
p = ggplot(diamonds, aes(color, fill = cut)) +
geom_bar() +
scale_fill_manual(values =
c(hcl(seq(15, 325, length.out = 5), 100, 65)[1:2],
"white",
hcl(seq(15, 325, length.out = 5), 100, 65)[3:5]),
drop = FALSE) +
guides(fill = guide_legend(ncol = 2, title.position = "top")) +
theme(legend.position = "bottom",
legend.key = element_rect(fill = "white"))
# Get the ggplot grob
g = ggplotGrob(p)
# Get the legend
leg = g$grobs[[which(g$layout$name == "guide-box")]]$grobs[[1]]
# Set up the two sub-titles as text grobs
st = lapply(c("First group", "Second group"), function(x) {
textGrob(x, x = 0, just = "left", gp = gpar(cex = 0.8)) } )
# Add a row to the legend gtable to take the legend sub-titles
leg = gtable_add_rows(leg, unit(1, "grobheight", st[[1]]) + unit(0.2, "cm"), pos = 3)
# Add the sub-titles to the new row
leg = gtable_add_grob(leg, st,
t = 4, l = c(2, 6), r = c(4, 8), clip = "off")
# Add a little more space between the two columns
leg$widths[[5]] = unit(.6, "cm")
# Move the legend to the right
leg$vp = viewport(x = unit(.95, "npc"), width = sum(leg$widths), just = "right")
# Put the legend back into the plot
g$grobs[[which(g$layout$name == "guide-box")]] = leg
# Draw the plot
grid.newpage()
grid.draw(g)
这提供了数字(来自那里)。
不过,我想做两件事。
第一组:我想将“一般”和“良好”分别重新标记为“非常好”和“高级”。因此,它们在每个组(第一和第二)中都非常好和优质。
我想做的第二件事是将它们放在一行中(第一组和第二组的两列并排放置,所有内容都在一行中,以节省垂直space.
我该怎么做?如果我的问题不清楚,请告诉我。我觉得我离这里很近了,但是这个解决方案并不能完全回答我的问题。非常感谢!
首先,您可以通过 scale_fill_manual
的 labels
参数简单地更改图例中出现的标签。其次,与其摆弄 gtable
,如果你想将这些组排成一行,这可能要求更高,你可以使用 ggnewscale
包,正如 在与您添加的 post 相同 link。虽然这个答案还使用了 relayer
包,但我的方法有点不同,因为我重新排列了层的顺序,这样就不需要 relayer
包了:
library(ggplot2)
library(ggnewscale)
diamonds$cut = factor(diamonds$cut, levels=c("Fair","Good", "Very Good",
"Premium","Ideal"))
labels <- levels(diamonds$cut)
labels <- setNames(labels, labels)
labels["Fair"] <- "Very Good"
labels["Good"] <- "Premium"
colors <- hcl(seq(15, 325, length.out = 5), 100, 65)
colors <- setNames(colors, levels(diamonds$cut))
ggplot() +
geom_bar(data = diamonds, aes(color, fill = cut)) +
scale_fill_manual(aesthetics = "fill", values = colors, labels = labels[1:2],
breaks = names(colors)[1:2], name = "First Group:",
guide = guide_legend(title.position = "left", order = 1)) +
new_scale_fill() +
geom_bar(data = diamonds, aes(color, fill = cut)) +
scale_fill_manual(aesthetics = "fill", values = colors, labels = labels[3:5],
breaks = names(colors)[3:5], name = "Second Group:",
guide = guide_legend(title.position = "left", order = 0)) +
theme(legend.position = "bottom",
legend.direction = "horizontal",
legend.key = element_rect(fill = "white"))
此问题基于
如下
library(ggplot2)
library(gtable)
library(grid)
diamonds$cut = factor(diamonds$cut, levels=c("Fair","Good"," ","Very Good",
"Premium","Ideal"))
p = ggplot(diamonds, aes(color, fill = cut)) +
geom_bar() +
scale_fill_manual(values =
c(hcl(seq(15, 325, length.out = 5), 100, 65)[1:2],
"white",
hcl(seq(15, 325, length.out = 5), 100, 65)[3:5]),
drop = FALSE) +
guides(fill = guide_legend(ncol = 2, title.position = "top")) +
theme(legend.position = "bottom",
legend.key = element_rect(fill = "white"))
# Get the ggplot grob
g = ggplotGrob(p)
# Get the legend
leg = g$grobs[[which(g$layout$name == "guide-box")]]$grobs[[1]]
# Set up the two sub-titles as text grobs
st = lapply(c("First group", "Second group"), function(x) {
textGrob(x, x = 0, just = "left", gp = gpar(cex = 0.8)) } )
# Add a row to the legend gtable to take the legend sub-titles
leg = gtable_add_rows(leg, unit(1, "grobheight", st[[1]]) + unit(0.2, "cm"), pos = 3)
# Add the sub-titles to the new row
leg = gtable_add_grob(leg, st,
t = 4, l = c(2, 6), r = c(4, 8), clip = "off")
# Add a little more space between the two columns
leg$widths[[5]] = unit(.6, "cm")
# Move the legend to the right
leg$vp = viewport(x = unit(.95, "npc"), width = sum(leg$widths), just = "right")
# Put the legend back into the plot
g$grobs[[which(g$layout$name == "guide-box")]] = leg
# Draw the plot
grid.newpage()
grid.draw(g)
这提供了数字(来自那里)。
不过,我想做两件事。
第一组:我想将“一般”和“良好”分别重新标记为“非常好”和“高级”。因此,它们在每个组(第一和第二)中都非常好和优质。
我想做的第二件事是将它们放在一行中(第一组和第二组的两列并排放置,所有内容都在一行中,以节省垂直space.
我该怎么做?如果我的问题不清楚,请告诉我。我觉得我离这里很近了,但是这个解决方案并不能完全回答我的问题。非常感谢!
首先,您可以通过 scale_fill_manual
的 labels
参数简单地更改图例中出现的标签。其次,与其摆弄 gtable
,如果你想将这些组排成一行,这可能要求更高,你可以使用 ggnewscale
包,正如 relayer
包,但我的方法有点不同,因为我重新排列了层的顺序,这样就不需要 relayer
包了:
library(ggplot2)
library(ggnewscale)
diamonds$cut = factor(diamonds$cut, levels=c("Fair","Good", "Very Good",
"Premium","Ideal"))
labels <- levels(diamonds$cut)
labels <- setNames(labels, labels)
labels["Fair"] <- "Very Good"
labels["Good"] <- "Premium"
colors <- hcl(seq(15, 325, length.out = 5), 100, 65)
colors <- setNames(colors, levels(diamonds$cut))
ggplot() +
geom_bar(data = diamonds, aes(color, fill = cut)) +
scale_fill_manual(aesthetics = "fill", values = colors, labels = labels[1:2],
breaks = names(colors)[1:2], name = "First Group:",
guide = guide_legend(title.position = "left", order = 1)) +
new_scale_fill() +
geom_bar(data = diamonds, aes(color, fill = cut)) +
scale_fill_manual(aesthetics = "fill", values = colors, labels = labels[3:5],
breaks = names(colors)[3:5], name = "Second Group:",
guide = guide_legend(title.position = "left", order = 0)) +
theme(legend.position = "bottom",
legend.direction = "horizontal",
legend.key = element_rect(fill = "white"))