带有映射到 x 的离散变量的刻度标签中的下标
Posted
技术标签:
【中文标题】带有映射到 x 的离散变量的刻度标签中的下标【英文标题】:Subscripts in tick labels with a discrete variable mapped to x 【发布时间】:2020-11-21 09:43:13 【问题描述】:我想知道如何在我的 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")
【问题讨论】:
一个很好的问题,有几个不同的可能答案。我已经更改了问题标题,使其更具描述性,并且这样对那些将来搜索的人更有用。我还稍微编辑了问题的文本,以匹配“ggplot2”文档和书籍中使用的术语。 【参考方案1】:一种可能的方法是使用最近发布的包“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 表达式时不完全相同,因为此处的字符保持不变,并且既不添加也不修改短划线周围的间距。在这种情况下,破折号明显更短。
【讨论】:
【参考方案2】:一种基于 'ggplot2' 的方法是将刻度标签设置为 R 表达式。 (此答案中的最后一个代码块是最佳答案,而其他代码块试图给出更一般的答案并提出替代方案。)
我们可以使用scale_x_discrete()
轻松地用 R 表达式替换字符数据值。但如此处所示,只有当我们使用有效的 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
中的值可以解析为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' 时的标签并不完全相同,因为此处的“减号”字符用于短划线,并且这些短划线周围的间距已调整为排版数学表达式。
【讨论】:
以上是关于带有映射到 x 的离散变量的刻度标签中的下标的主要内容,如果未能解决你的问题,请参考以下文章