【问题标题】:Selective bold font on graph图表上的选择性粗体字体
【发布时间】:2018-12-18 00:36:58
【问题描述】:

我正在用汇总统计数据注释我的图表。我想使用 bold 字体快速将用户的注意力吸引到按组划分的最佳/最差统计数据上。突出显示的数字需要在运行时由数据本身确定。

这是一个使用 ChickWeight 数据集的示例,显示了基于日粮的雏鸡体重变化:

library(ggplot2)
library(dplyr)

# Calculate end vs start weights
df <- merge(filter(ChickWeight, Time==21), filter(ChickWeight, Time==0), by=c("Chick", "Diet"))
df$dWeight <- df$weight.x - df$weight.y

# Summary statistics: sd & mean
df.stat <- do.call(data.frame, 
                   aggregate(dWeight ~ Diet, 
                             data=df, 
                             FUN = function(x) c(SD=sd(x), MN=mean(x))))

ggplot(data = df) + 
    facet_grid(Diet ~ .) +
    geom_histogram(binwidth=10, aes(x=dWeight)) + 
    geom_vline(data=df.stat, aes(xintercept = dWeight.MN), color="black") + 
    geom_text(data=df.stat, aes(x=Inf, 
                                y=Inf, 
                                label = sprintf("\nmean = %4.1f\nsd = %4.1f", 
                                                dWeight.MN, dWeight.SD), 
                                hjust=1, 
                                vjust=1)) 

在下图中,我只想突出显示以下文本:
在第 3 组中,“mean = 229.5”将变为“mean = 229.5
在第 4 组中,“sd = 43.9”将变为“sd = 43.9

【问题讨论】:

  • 只将文本的一部分加粗,尤其是由变量给出的部分是很棘手的,看起来你需要这样的东西stackoverflow.com/a/50768373/1320535
  • @JuliusVainora,该技术似乎需要两次 geom_text() 调用。一个打印非粗体文本,另一个打印粗体文本,留下其他部分phantom()。我不确定如何与facet_grid() 一起使用。我完全不知道如何在 plotmath 中使用expression()bquote()substitute() 等。每次尝试都会给出一个新的错误消息,导致另一个兔子洞追逐。

标签: r ggplot2


【解决方案1】:

如果你不想muck around with parsing,你可以在你的情节标签中添加一个条件,你会非常接近。

数据

df.plot <- df %>%
    # Combine df and df.stat -
    # this also removes the calls to df.stat in your secondary geoms.
    left_join(df.stat, by = "Diet") %>%
    # Add global maximum of MN and global minimum of SD to every row.
    mutate(dWeight.MN.max = max(dWeight.MN),
           dWeight.SD.min = min(dWeight.SD))

代码

ggplot(data = df.plot) + 
    facet_grid(Diet ~ .) +
    geom_histogram(binwidth = 10, aes(x = dWeight)) + 
    geom_vline(aes(xintercept = dWeight.MN), color="black") + 
    geom_text(aes(x = Inf, 
                  y = Inf, 
                  label = sprintf("\nmean = %4.1f", dWeight.MN), 
                  hjust = 1,
                  vjust = 1,
                  # bold if mean == mean maximum
                  fontface = ifelse(dWeight.MN == dWeight.MN.max, 2, 1))) +
    geom_text(aes(x = Inf, 
                  y = Inf, 
                  label = sprintf("\n\nsd = %4.1f", dWeight.SD), 
                  hjust = 1,
                  vjust = 1,
                  # bold if sd == sd minimum
                  fontface = ifelse(dWeight.SD == dWeight.SD.min, 2, 1))) +
    theme_gray()

说明

使用fontface =,您可以将geom_text() 斜体粗体。 表达式中的 ifelse() 检查该值是否等于全局最大值/最小值,如果为真则将文本设置为粗体 (= 2),如果为假则将其保留为纯文本 (= 1)。

【讨论】:

  • 使用您的技术和latex2exp 库,我能够将geom_text 语句修改为仅将数字加粗,如下所示:label = TeX(sprintf(ifelse(df.plot$dWeight.MN==df.plot$dWeight.MN.max, "mean = \\textbf{%4.1f}", "mean = %4.1f"), df.plot$dWeight.MN)))
  • 干得好!您应该发布您的方法作为答案并自己接受。这样,这个问题将不再被标记为“开放”。请参阅here 如何接受答案。
【解决方案2】:

借鉴@Roman 的ifelse 理念,这是一个使用latex2exp 库构建LaTeX 字符串的解决方案,该字符串允许在字符串中更改粗体 字体。 latex2exp 将 TeX 字符串转换为绘图表达式。

仍然不完美,也不能扩展到两行文本之外。 latex2expdoes not appear to support newlines,强迫我改用overset

另一个 LaTeX 选项是 {n x 1} 矩阵,但 latex2exp 也不支持矩阵(运行 latex2exp_supported() 以查看支持哪些 LaTeX 表达式)。

或者两个单独的geom_text 命令,如果在用户调整或缩放绘图时有可靠的间距和对齐方式。

此解决方案仅限于 2 行,只能彼此中心对齐。

数据

library(ggplot2)
library(dplyr)
library(latex2exp)

# Calculate end - start weights
df <- inner_join(filter(ChickWeight, Time==21), 
                 filter(ChickWeight, Time==0), 
                 by=c("Chick", "Diet")) %>%
      mutate(dWeight=weight.x-weight.y) %>% 
      select(Chick, Diet, dWeight)

# Summary statistics: sd & mean
df.stats <- df %>% 
            group_by(Diet) %>% 
            summarise(MN=mean(dWeight), SD=sd(dWeight)) %>% 
            mutate(is.max.MN=(MN==max(MN))) %>% 
            mutate(is.min.SD=(SD==min(SD)))

ggplot 命令

ggplot(data=df) + 
    facet_grid(Diet ~ .) +
    geom_histogram(binwidth=10, aes(x=dWeight)) + 
    geom_vline(data=df.stats, aes(xintercept = MN), color="black") + 
    geom_text(data=df.stats,
              aes(x=Inf, 
                  y=Inf, 
                  hjust=1, 
                  vjust=1),
              label = TeX(paste("\\overset{mean =", 
                                sprintf(ifelse(df.stats$is.max.MN, "\\textbf{%4.1f}", "%4.1f"), df.stats$MN),
                                "}{sd =",
                                sprintf(ifelse(df.stats$is.min.SD, "\\textbf{%4.1f} $", "%4.1f"), df.stats$SD),
                                "}"
                          )))

geom_textlabel 位于 aes 函数之外,该函数似乎没有继承数据命名空间。

此外,这个 ggplot 命令会生成一条警告消息(TeX 语句):
在 is.na(x) 中:is.na() 应用于类型为 ' 的非(列表或向量)表达式'

【讨论】:

    猜你喜欢
    • 2015-11-14
    • 1970-01-01
    • 2015-07-23
    • 2012-07-09
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多