【问题标题】:ggplot2: color individual words in title to match colors of groupsggplot2:为标题中的单个单词着色以匹配组的颜色
【发布时间】:2018-09-18 23:46:27
【问题描述】:

我最近在《经济学人》上看到了一个折线图,其中title had colored words to match the colors of the groups used in the line chart。我想知道如何使用 ggplot2 对象来做到这一点。这里有一些代码可以制作一个折线图,其中包含除标题中的彩色单词之外的所有内容,如经济学家文章。在底部,我显示了所需的输出。

这个问题不是关于显示此信息的理论方法(如直接标记或图例),而是具体关于在标题中为单个单词着色。

data <- data.frame(
    group = rep(c('affluence', 'poverty'), each = 6),
    year = rep(c(1970, 1980, 1990, 2000, 2010, 2012), 2),  
    concentration = c(.125, .12, .14, .13, .145, .146, .068, .09, .125, .119, .13, .135)
)

library(ggplot2)

ggplot(data, aes(year, concentration, color = group)) +
    geom_line(size = 1.5) +
    geom_point(size = 4) +
    scale_y_continuous(limits = c(0, .15)) +
    labs(
        x = NULL, y = NULL, 
        title = 'Concentration of affluence and poverty nationwide'
    ) +
    theme_minimal() +
    theme(
        legend.position = 'none'
    ) +
    scale_color_manual(values = c('#EEB422', '#238E68'))

【问题讨论】:

标签: r ggplot2


【解决方案1】:

此解决方案基于 Displaying text below the plot generated by ggplot2Colorize parts of the title in a plot(感谢那里的贡献者!)。

通过对文本使用phantom 占位符,我们避免了(大部分)位置的硬编码。

# create text grobs, one for each color
library(grid)
t1 <- textGrob(expression("Concentration of " * phantom(bold("affluence")) * "and" * phantom(bold("poverty")) * " nationwide"),
               x = 0.5, y = 1.1, gp = gpar(col = "black"))

t2 <- textGrob(expression(phantom("Concentration of ") * bold("affluence") * phantom(" and poverty nationwide")),
               x = 0.5, y = 1.1, gp = gpar(col = "#EEB422"))

t3 <- textGrob(expression(phantom("Concentration of affluence and ") * bold("poverty") * phantom(" nationwide")),
               x = 0.5, y = 1.1, gp = gpar(col = "#238E68"))

# plot and add grobs with annotation_custom
ggplot(data, aes(year, concentration, color = group)) +
  geom_line(size = 1.5) +
  geom_point(size = 4) +
  annotation_custom(grobTree(t1, t2, t3)) +
  scale_y_continuous(limits = c(0, 0.15)) +
  scale_color_manual(values = c("#EEB422", "#238E68")) +
  coord_cartesian(clip = "off") +
  labs(x = NULL, y = NULL) +
  theme_minimal() +
  theme(legend.position = 'none',
        # add some extra margin on top
        plot.margin = unit(c(4, 1, 1, 1), "lines"))


对于大量彩色单词,不同expressions 的创建应该更多地以编程方式完成。参见例如不错的multiTitle 函数在base 情节的类似问题中:title: words in different colors?,这在ggplot 中也应该有用。

【讨论】:

    【解决方案2】:

    这是使用ggtext 包的简单且更通用的方法

    制作:

    library(ggtext) 
    
    ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
      geom_point(size = 3) +
      scale_color_manual(
        name = NULL,
        values = c(setosa = "#0072B2", virginica = "#009E73", versicolor = "#D55E00"),
        labels = c(
          setosa = "<i style='color:#0072B2'>I. setosa</i>",
          virginica = "<i style='color:#009E73'>I. virginica</i>",
          versicolor = "<i style='color:#D55E00'>I. versicolor</i>")
      ) +
      labs(
        title = "**Fisher's *Iris* dataset**  
        <span style='font-size:11pt'>Sepal width vs. sepal length for 
        <span style='color:#0072B2;'>setosa</span>, 
        <span style='color:#D55E00;'>versicolor</span>, and
        <span style='color:#009E73;'>virginica</span>
        </span>",
        x = "Sepal length (cm)", y = "Sepal width (cm)"
      ) +
      theme_minimal() +
      theme(
        plot.title = element_markdown(lineheight = 1.1),
        legend.text = element_markdown(size = 11)
      )
    

    【讨论】:

      【解决方案3】:

      annotation_custom 有点麻烦的解决方案:

      ggplot(dat, aes(year, concentration, color = group)) +
        geom_line(size = 1.5) +
        geom_point(size = 4) +
        scale_y_continuous(limits = c(0, 0.16)) +
        labs(x = NULL, y = NULL, title = ' ') +
        theme_minimal() +
        theme(legend.position = 'none') +
        scale_color_manual(values = c('#EEB422', '#238E68')) +
        annotation_custom(textGrob('Concentration of', gp = gpar(col = 'black')), 
                          xmin = 1972, xmax = 1972, ymin = 0.165, ymax = 0.165) +
        annotation_custom(textGrob('affluence', gp = gpar(col = '#EEB422', fontface = 'bold')), 
                          xmin = 1975.7, xmax = 1975.7, ymin = 0.165, ymax = 0.165) +
        annotation_custom(textGrob(' and ', gp = gpar(col = 'black')), 
                          xmin = 1977.65, xmax = 1977.65, ymin = 0.165, ymax = 0.165) +
        annotation_custom(textGrob('poverty', gp = gpar(col = '#238E68', fontface = 'bold')), 
                          xmin = 1979.35, xmax = 1979.35, ymin = 0.165, ymax = 0.165) +
        annotation_custom(textGrob('nationwide', gp = gpar(col = 'black')), 
                          xmin = 1982, xmax = 1982, ymin = 0.165, ymax = 0.165)
      

      给出:

      这种方法的主要缺点是它需要大量调整参数才能在正确的位置获得标题的单词。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-29
        • 1970-01-01
        • 2021-07-19
        • 1970-01-01
        • 1970-01-01
        • 2021-05-29
        • 2014-05-15
        相关资源
        最近更新 更多