帖子使用不同颜色自定义 ggplot2 轴标签描述了当数据源中的每个(离散)值都有其自己的相应标签时如何更改每个标签的颜色。但是,当您拥有较大的数据集并且该数据集中的每个值不由其自己的值表示(这很快就会成为连续值的情况)时,如何有效地引用和格式化每个标签?
以下内容适用于 ggplot2 3.0.0。对于 ggplot2 的早期版本,
ggplot_build(plt1)$layout$panel_params[[1]]$y.label
的确切结构会有所不同。
在下面的可重现数据集和相应图表中,您将看到数据框 df 中的 A 列和 B 列都有 10 个观测值,并且 y 轴上显示的 B 分配有 4 个标签。使用
ggplot_build()
和 theme()
,您可以按照您喜欢的方式引用 y 标签并设置其格式。下面,负数和正数分别指定为红色和蓝色。零仍然是黑色的。
片段
# settings
library(ggplot2)
set.seed(123)
# data
A = rnorm(10, mean=0, sd=1)
B = rnorm(10, mean=0, sd=1)
df <- data.frame(A,B)
# initial plot
plt1 <- ggplot(data = df) + aes(x=A, y=B)+geom_line()
# retrieve lables using ggplot_build()
yLabVals <- as.numeric(ggplot_build(plt1)$layout$panel_params[[1]]$y.labels)
# create color list
yLabs <- ifelse(yLabVals < 0, "red", "blue")
yLabs[yLabVals == 0] <- 'black'
# plot
plt2 <- plt1 + theme(axis.text.y = element_text(angle = 0, hjust = 1, colour = yLabs))
plt2
剧情
对于 ggplot2 >= 3.3.0,比例现在使用 proto。这是一个似乎有效的新技巧。整个方法仍然非常脆弱,并且 ggplot 会发出有关向
element_text
提供向量的警告。值得找到一个更强大的解决方案。
# settings
library(ggplot2)
set.seed(123)
# data
A = rnorm(10, mean=0, sd=1)
B = rnorm(10, mean=0, sd=1)
df <- data.frame(A,B)
# initial plot
plt1 <- ggplot(data = df) + aes(x=A, y=B)+geom_line()
# retrieve lables using ggplot_build()
yLabVals <- as.numeric(ggplot_build(plt1)$layout$panel_params[[1]]$y$get_labels())
# create color list
yLabs <- ifelse(yLabVals < 0, "red", "blue")
yLabs[yLabVals == 0] <- 'black'
# plot
plt2 <- plt1 + theme(axis.text.y = element_text(angle = 0, hjust = 1, colour = yLabs))
plt2
使用
labels
中的 scale_y_continuous
与 ggtext::element_markdown()
配对,可以更惯用地对轴文本进行选择性着色。
scale_y_continuous
接受一个参数 labels
,它可以是一个函数。此函数将中断值映射到绘图上显示的文本。
使用
ggtext
包将 y 轴文本解释为 markdown。
library(ggplot2)
set.seed(123)
df <- data.frame(
x = rnorm(10, mean = 0, sd = 1),
y = rnorm(10, mean = 0, sd = 1)
)
ggplot(df, aes(x, y)) +
geom_line() +
scale_y_continuous(
labels = \(break_value) {
dplyr::case_when(
break_value %in% c(-1, -2) ~ paste0("<span style = 'color:red'>", break_value, "</span>"),
break_value == 1 ~ paste0("<span style = 'color:blue'>", break_value, "</span>"),
TRUE ~ as.character(break_value)
)
}
) +
theme(
axis.text.y = ggtext::element_markdown()
)