1

我想知道如何在我的 x 轴刻度标签中添加下标。不像大多数其他帖子那样在轴标签中,因此来自数据框中已经存在的值。

这是一个可重现的代码示例,我希望括号中的字母是下标。

p_t<- c(rep("FW - P[H]",3),rep("FW - P[L]",3),rep("FW - F",3),rep("FW - SSWB",3),rep("C - F",3),rep("C - P[L]",3),rep("C - P[H]",3))
s_t<-rep(c("A","B","C"),7)
c_t <-c(0,1,2,+
              0,3,2,+
              0,4,3,+
              0,3,4,+
              0,6,5,+
              0,2,4,+
              0,7,2)
df_t1<-data.frame(p_t,s_t,c_t)

ggplot(data=df_t1,aes(y=c_t, x=p_t,fill = s_t))+ 
  geom_bar(stat="identity",
           color="black")
4

2 回答 2

0

一种可能的方法是使用最近发布的包“ggtext”,但它的使用需要更改示例数据中下标的编码,因为“ggtetxt”实现了对 Markdown 和 HTML 标记的支持。在第一个代码块中,我更改了示例数据,但如果数据与问题中的数据相同,gsub()则可以使用,如第二个代码块所示,将方括号替换为动态下标的 HTML 编码。

library(ggplot2)
library(ggtext)

p_t <- c(rep("FW-P<sub>H</sub>", 3), rep("FW-P<sub>L</sub>", 3), rep("FW-F", 3),
        rep("FW-SSWB", 3), rep("C-F", 3), rep("C-P<sub>L</sub>", 3),
        rep("C-P<sub>H</sub>", 3))
s_t <- rep(c("A", "B", "C"), 7)
c_t <- c(0, 1, 2, +0, 3, 2, +0, 4, 3, +0, 3, 4, +0, 6, 5, +0, 2, 4, +0, 7, 2)
df_t1 <- data.frame(p_t, s_t, c_t)

ggplot(data = df_t1, aes(y = c_t, x = p_t, fill = s_t)) + 
  geom_bar(stat = "identity",
           color = "black") +
  theme(axis.text.x = element_markdown())

在此处输入图像描述

字符串替换可以即时完成,scale_x_discrete()以便在需要时也可以自动转换为 HTML 标记。

p_t <- c(rep("FW - P[H]", 3), rep("FW - P[L]", 3), rep("FW - F", 3),
         rep("FW - SSWB", 3), rep("C - F", 3), rep("C - P[L]", 3),
         rep("C - P[H]", 3))
s_t <- rep(c("A", "B", "C"), 7)
c_t <- c(0, 1, 2, +0, 3, 2, +0, 4, 3, +0, 3, 4, +0, 6, 5, +0, 2, 4, +0, 7, 2)
df_t1 <- data.frame(p_t, s_t, c_t)

ggplot(data = df_t1, aes(y = c_t, x = p_t, fill = s_t)) + 
  geom_bar(stat = "identity",
           color = "black") +
  scale_x_discrete(labels = function(x) {gsub("\\[", "<sub>", gsub("\\]", "</sub>", x))}) +
  theme(axis.text.x = element_markdown()) 

注意:刻度标签与使用 R 表达式时不完全相同,因为此处的字符保持不变,并且既不添加也不修改短划线周围的间距。在这种情况下,破折号明显更短。

于 2020-07-31T16:18:32.690 回答
0

基于“ggplot2”的一种方法是将刻度标签设置为 R 表达式。(此答案中的最后一个代码块是最佳答案,而其他代码块试图给出更一般的答案并提出替代方案。)

我们可以使用 R 表达式轻松替换字符数据值scale_x_discrete()。但如此处所示,只有当我们使用有效的 R 名称作为数据值字符串时,这才是简单的。(图中的列根据存储在 中的值按字母顺序显示p_t,除非使用breaks参数更改此顺序scale_x_discrete,因此此示例的顺序不同。)

p_t <- c(rep("a", 3), rep("b", 3), rep("c", 3),
    rep("d", 3), rep("e", 3), rep("f", 3),
    rep("g", 3))
s_t <- rep(c("A", "B", "C"), 7)
c_t <- c(0, 1, 2, +0, 3, 2, +0, 4, 3, +0, 3, 4, +0, 6, 5, +0, 2, 4, +0, 7, 2)
df_t1 <- data.frame(p_t, s_t, c_t)

ggplot(data = df_t1, aes(y = c_t, x = p_t, fill = s_t)) +
  geom_bar(stat = "identity",
           color = "black") +
  scale_x_discrete(labels = c(a = expression(FW - P[H]), 
                              b = expression(FW - P[L]), 
                              c = expression(FW - F),
                              d = expression(FW - SSWB), 
                              e = expression(C - F), 
                              f = expression(C - P[L]),
                              g = expression(C - P[H])))

数据中的值使用表达式的命名向量进行转换。上面的代码还不是问题的完整答案,但它比正确的答案更容易理解,我在下面分两个阶段展示。不同之处在于我们需要在创建标签向量时使用反引号来保护名称,因为数据值包含在 R nanes 中使用时需要特殊处理的字符。

p_t <- c(rep("FW - P[H]", 3), rep("FW - P[L]", 3), rep("FW - F", 3),
    rep("FW - SSWB", 3), rep("C - F", 3), rep("C - P[L]", 3),
    rep("C - P[H]", 3))
s_t <- rep(c("A", "B", "C"), 7)
c_t <- c(0, 1, 2, +0, 3, 2, +0, 4, 3, +0, 3, 4, +0, 6, 5, +0, 2, 4, +0, 7, 2)
df_t1 <- data.frame(p_t, s_t, c_t)

ggplot(data = df_t1, aes(y = c_t, x = p_t, fill = s_t)) +
  geom_bar(stat = "identity",
           color = "black") +
  scale_x_discrete(labels = c(`FW - P[H]` = expression(FW - P[H]), 
                              `FW - P[L]` = expression(FW - P[L]), 
                              `FW - F` = expression(FW - F),
                              `FW - SSWB` = expression(FW - SSWB), 
                              `C - F` = expression(C - F), 
                              `C - P[L]` = expression(C - P[L]),
                              `C - P[H]` = expression(C - P[H])))

我展示了这些更简单的案例,因为问题非常具体,对于大多数未来的读者来说,一个更简单的答案可能就是他们所需要的。这种方法可用于选择性地替换单个刻度标签,而不是如上所示的全部。

在此处输入图像描述

我们还可以自动构建作为参数传递给的向量labels

labels.vec <- parse(text = unique(df$p_t))
names(labels.vec) <- unique(df$p_t)

ggplot(data = df_t1, aes(y = c_t, x = p_t, fill = s_t)) +
  geom_bar(stat = "identity",
           color = "black") +
  scale_x_discrete(labels = c(labels.vec))

此代码只要求df$p_t可以将 in 中的值解析为 R 表达式。换句话说,这个解决方案完全由存储在数据框中的值驱动。

最简单且推荐的方法是即时进行解析。由于参数命名和定义中的位置parse()我们不能直接parse作为参数传递给参数labels,我们需要定义一个匿名函数作为包装器。

ggplot(data = df_t1, aes(y = c_t, x = p_t, fill = s_t)) +
  geom_bar(stat = "identity",
           color = "black") +
  scale_x_discrete(labels = function(x) {parse(text = x)})

最后一个示例与使用“ggtext”一样简单或更简单,但不允许使用嵌入的 HTML 标签添加颜色等,就像使用“ggtext”一样。

注意:标签与使用 'ggtext' 时的标签不完全相同,因为这里的“减号”字符用于破折号,并且这些破折号周围的间距已调整为排版数学表达式。

于 2020-07-31T18:31:07.447 回答