R:将自定义图例添加到 ggplot

Posted

技术标签:

【中文标题】R:将自定义图例添加到 ggplot【英文标题】:R: add custom legend to ggplot 【发布时间】:2021-01-05 11:12:49 【问题描述】:

我有以下情节:

并想添加如下图例:

这是我用来生成绘图的代码:

library(data.table)
library(ggplot2)

blue <- "#4472C4"
green <- "#548235"
red <- "#C55A11"
redblood <- "#C00000"

DT <- data.table(student = c("Jane", "Sam", "Tim", "Kate", "Claire"),
                 grade = c(10, 14, 8, 9, 19))

b0 <- 13

DT[, gradeHat := b0]
DT[, e := grade - gradeHat]
DT[, SS := sum(e**2)]

DT[, id := 1:nrow(DT)]
DT[, xmin := id]
DT[, xmax := id + abs(e)/20*3]
DT[, ymin := min(grade, gradeHat), id]
DT[, ymax := max(grade, gradeHat), id]
DT[, student := factor(student, levels = student)]

gg <- ggplot(DT) +
  geom_segment(aes(x = student, xend = student, y = grade, yend = gradeHat),
               color = redblood, size = 1.3) +
  geom_rect(aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
            fill = redblood, alpha = .4) +
  geom_hline(yintercept = b0, color = green, alpha = .7, size = 1, linetype = "dashed") +
  geom_point(aes(student, grade), color = blue, size = 4) +
  geom_point(aes(student, gradeHat), color = green, size = 4) +
  scale_y_continuous(breaks = 0:20, limits = c(0, 20)) +
  coord_fixed(.15) +
  theme_classic()

plot(gg)

【问题讨论】:

【参考方案1】:

不是您问题的完整解决方案......但我目前能想到的最好的解决方案:

    要在 ggplot 中获得图例,您必须在美学上进行映射,即,您必须映射到 coloraes() 内的 colorfill 上,而不是将颜色设置为参数。为此,您可以使用占位符或标签,例如fill="SS"geom_rect

    要获得正确的颜色,您可以使用scale_color/fill_manual。使用标签可以很容易地分配正确的颜色。

    接下来,要正确设置图例的样式,您可以使用guide_legend 及其参数override.aes 来设置颜色图例的形状和线型。

    默认情况下,colorfill 图例之间有一些间距,但可以通过 legend.spacinglegend.margintheme() 中删除。

    最后一部分是给图例标签上色。这可以通过ggtext 包实现,该包通过主题选项legend.text = element_markdown() 允许使用html 和CSS 设置图例条目的样式。

很遗憾,我无法弄清楚如何在您的 gradeHat 上戴上宽帽。

library(data.table)
library(ggplot2)

blue <- "#4472C4"
green <- "#548235"
red <- "#C55A11"
redblood <- "#C00000"

DT <- data.table(student = c("Jane", "Sam", "Tim", "Kate", "Claire"),
                 grade = c(10, 14, 8, 9, 19))

b0 <- 13

DT[, gradeHat := b0]
DT[, e := grade - gradeHat]
DT[, SS := sum(e**2)]

DT[, id := 1:nrow(DT)]
DT[, xmin := id]
DT[, xmax := id + abs(e)/20*3]
DT[, ymin := min(grade, gradeHat), id]
DT[, ymax := max(grade, gradeHat), id]
DT[, student := factor(student, levels = student)]

ggplot(DT) +
  geom_segment(aes(x = student, xend = student, y = grade, yend = gradeHat, color = "error"),
               , size = 1.3) +
  geom_rect(aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = "SS"), alpha = .4) +
  geom_hline(yintercept = b0, color = green, alpha = .7, size = 1, linetype = "dashed") +
  geom_point(aes(student, grade, color = "grade"), size = 4) +
  geom_point(aes(student, gradeHat, color = "gradeHat"), size = 4) +
  scale_color_manual(breaks = c("grade", "gradeHat", "error"), 
                     values = c(grade = blue, gradeHat = green, error = red),
                     labels = c(grade = glue::glue("<span style = 'color: blue;'>grade</span>"),
                                gradeHat = glue::glue("<span style = 'color: green;'>gradeHat</span>"), 
                                error = glue::glue("<span style = 'color: red;'>error</span>"))) +
  scale_fill_manual(values = c(SS = redblood), labels = c(SS = glue::glue("<span style = 'color: #C0000066; '>SS</span>"))) +
  guides(color = guide_legend(order = 1, override.aes = list(shape = c(16, 16, NA), linetype = c("blank", "dashed", "solid")))) +
  scale_y_continuous(breaks = 0:20, limits = c(0, 20)) +
  coord_fixed(.15) +
  theme_classic() +
  theme(legend.position = "bottom", 
        legend.spacing = unit(0, "pt"), 
        legend.margin = margin(r = 0, l = 0),
        legend.text = ggtext::element_markdown()) +
  labs(color = NULL, fill = NULL)

【讨论】:

哈哈!相隔2秒!不过方法略有不同,所以我们都很好!【参考方案2】:

是的,这(几乎)是可能的:

gg <- ggplot(DT) +
  geom_segment(aes(x = student, xend = student, y = grade, yend = gradeHat,
               color = "Error"), size = 1.3) +
  geom_rect(aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = "SS"),
            alpha = .4) +
  geom_hline(aes(alpha = "Grade", yintercept = 13), linetype = 2,
             color = green, size = 1, key_glyph = "pointrange") +
  geom_point(aes(student, grade, shape = "Grade"), color = blue, size = 4) +
  geom_point(aes(student, gradeHat), color = green, size = 4)  +
  scale_y_continuous(breaks = 0:20, limits = c(0, 20)) +
  scale_shape_manual(values = 19, name = NULL, guide = guide_legend(order = 1)) +
  scale_color_manual(values = redblood, name = NULL, 
                     guide = guide_legend(order = 3)) +
  scale_alpha_manual(breaks = "Grade", values = 1,
                    guide = guide_legend(order = 2,
                                         override.aes = list(color = green)),
                    name = "") +
  scale_fill_manual(values = redblood, name = NULL) +
  coord_fixed(.15) +
  theme_classic() +
  theme(legend.position = "bottom",
        legend.key.width = unit(20, "points")) 

plot(gg)

【讨论】:

以上是关于R:将自定义图例添加到 ggplot的主要内容,如果未能解决你的问题,请参考以下文章

R语言ggplot2可视化自定义图例实战:添加自定义的图例添加填充色的图例

R语言ggplot2可视化并自定义配置图例的位置到可视化图像的顶部配置折叠成两行显示图例并添加图像形状的子图(ggplot2 legend in two rows with guides fill

R语言ggplot2可视化:ggplot2可视化将图像的图例(legend)移动到图像内部自定义图例所处的位置

R语言ggplot2可视化自定义图例标签间距实战:自定义图例标签间距自定义图例与图像之间的间距

R语言ggplot2可视化:在ggplot2中将图例(legend)移到图内自定义图例所处的位置自定义图例背景图例所处边框的颜色

R语言ggplot2可视化分面图(faceting): 堆叠柱状图的分面图编写自定义函数在分面图的左侧添加图例信息(legend)