在条形图上垂直对齐 geom_text 图层
Aligning a geom_text layer vertically on a bar chart
我目前将 geom_text 设置为条形图的中心...
library(dplyr)
library(ggplot2)
enroll_bar <- enroll_cohort %>%
filter(chrt_grad != 2013) %>%
mutate(college_enrolled = factor(college_enrolled),
chrt_grad = factor(chrt_grad)) %>%
mutate(label_height = cumsum(n)) %>%
ggplot() +
geom_col(mapping = aes(x = chrt_grad,
y = n,
fill = fct_rev(college_enrolled))) +
geom_text(aes(x = chrt_grad, y = label_height, label = n), color = "white",
position = position_stack(vjust = 0.5)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1))) +
labs(x = NULL, y = NULL) +
scale_fill_manual(labels = c("Enrolled", "Not Enrolled"),
values = c("#00aeff", "#005488"))
如何垂直对齐文本,以便将 geom_text 图层设置在每个栏的相同 y 轴位置?另外,有没有办法做到这一点,无论 y 轴的比例如何,文本始终对齐,因为这是一个参数化报告,y 轴值随每个报告而变化?
如果您希望标签的高度统一,您可以在 geom_text()
外的 y
中指定一个 y
和您要查找的高度。
我使用了数据集diamonds
。列太长了 non-uniform,白色文本不可见,所以我将顶部标签更改为黑色。
因为底部组的最低值真的很低,所以我将其设置为 100。顶部组设置为 5000。本质上,我创建了一个向量 -- 100, 5000, 100, 5000, 100... 和依此类推,使用 rep()
(重复)。
数据设置不同,因为您没有将其包含在您的问题中。不过,这应该无关紧要。
图书馆(tidyverse)
diamonds %>%
filter(color %in% c("E", "I")) %>%
ggplot(aes(x = cut,
fill = color)) +
geom_bar() +
geom_text(aes(label = ..count..), # use the count
y = rep(c(100, 5000), # btm label y = 100, top label y = 5K
times = 5),
stat = 'count',
color = rep(c("white", "black"), # btm label white, top black
times = 5),
position = position_stack(vjust = .5)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1))) +
labs(x = NULL, y = NULL) +
scale_fill_manual(labels = c("E", "I"),
values = c("#00aeff", "#005488")) +
theme_bw()
您可以使用 if_else
(或 case_when
用于 >2 个组)为每个组设置统一的标签高度。对于单个图,您可以简单地设置一个值,例如 label_height = if_else(college_enrolled == "Enrolled", 20000, 3000)
。要使多个绘图的相对高度一致,您可以将 label_height
设置为 y-axis 范围的比例:
library(tidyverse)
# make a fake dataset
enroll_cohort <- expand_grid(
chrt_grad = factor(2014:2021),
college_enrolled = factor(c("Enrolled", "Not Enrolled")),
) %>%
mutate(
n = sample(18000:26000, 16),
n = if_else(college_enrolled == "Enrolled", n, as.integer(n / 3))
)
enroll_bar <- enroll_cohort %>%
group_by(chrt_grad) %>% # find each bar's height by summing up `n`
mutate(bar_height = sum(n)) %>% # within each year
ungroup() %>%
mutate(label_height = if_else(
college_enrolled == "Enrolled",
max(bar_height) * .6, # axis height is max() of bar heights;
max(bar_height) * .1 # set label_height as % of axis height
)) %>%
ggplot() +
geom_col(aes(x = chrt_grad, y = n, fill = college_enrolled), color = NA) +
geom_text(
aes(x = chrt_grad, y = label_height, label = n),
color = "white"
) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1))) +
labs(x = NULL, y = NULL) +
scale_fill_manual(values = c("#00aeff", "#005488"))
如果我们生成另一个具有不同 n
值范围的数据集——例如,~1200 - ~2000——文本标签保持在相同的相对位置:
我目前将 geom_text 设置为条形图的中心...
library(dplyr)
library(ggplot2)
enroll_bar <- enroll_cohort %>%
filter(chrt_grad != 2013) %>%
mutate(college_enrolled = factor(college_enrolled),
chrt_grad = factor(chrt_grad)) %>%
mutate(label_height = cumsum(n)) %>%
ggplot() +
geom_col(mapping = aes(x = chrt_grad,
y = n,
fill = fct_rev(college_enrolled))) +
geom_text(aes(x = chrt_grad, y = label_height, label = n), color = "white",
position = position_stack(vjust = 0.5)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1))) +
labs(x = NULL, y = NULL) +
scale_fill_manual(labels = c("Enrolled", "Not Enrolled"),
values = c("#00aeff", "#005488"))
如何垂直对齐文本,以便将 geom_text 图层设置在每个栏的相同 y 轴位置?另外,有没有办法做到这一点,无论 y 轴的比例如何,文本始终对齐,因为这是一个参数化报告,y 轴值随每个报告而变化?
如果您希望标签的高度统一,您可以在 geom_text()
外的 y
中指定一个 y
和您要查找的高度。
我使用了数据集diamonds
。列太长了 non-uniform,白色文本不可见,所以我将顶部标签更改为黑色。
因为底部组的最低值真的很低,所以我将其设置为 100。顶部组设置为 5000。本质上,我创建了一个向量 -- 100, 5000, 100, 5000, 100... 和依此类推,使用 rep()
(重复)。
数据设置不同,因为您没有将其包含在您的问题中。不过,这应该无关紧要。
图书馆(tidyverse)
diamonds %>%
filter(color %in% c("E", "I")) %>%
ggplot(aes(x = cut,
fill = color)) +
geom_bar() +
geom_text(aes(label = ..count..), # use the count
y = rep(c(100, 5000), # btm label y = 100, top label y = 5K
times = 5),
stat = 'count',
color = rep(c("white", "black"), # btm label white, top black
times = 5),
position = position_stack(vjust = .5)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1))) +
labs(x = NULL, y = NULL) +
scale_fill_manual(labels = c("E", "I"),
values = c("#00aeff", "#005488")) +
theme_bw()
您可以使用 if_else
(或 case_when
用于 >2 个组)为每个组设置统一的标签高度。对于单个图,您可以简单地设置一个值,例如 label_height = if_else(college_enrolled == "Enrolled", 20000, 3000)
。要使多个绘图的相对高度一致,您可以将 label_height
设置为 y-axis 范围的比例:
library(tidyverse)
# make a fake dataset
enroll_cohort <- expand_grid(
chrt_grad = factor(2014:2021),
college_enrolled = factor(c("Enrolled", "Not Enrolled")),
) %>%
mutate(
n = sample(18000:26000, 16),
n = if_else(college_enrolled == "Enrolled", n, as.integer(n / 3))
)
enroll_bar <- enroll_cohort %>%
group_by(chrt_grad) %>% # find each bar's height by summing up `n`
mutate(bar_height = sum(n)) %>% # within each year
ungroup() %>%
mutate(label_height = if_else(
college_enrolled == "Enrolled",
max(bar_height) * .6, # axis height is max() of bar heights;
max(bar_height) * .1 # set label_height as % of axis height
)) %>%
ggplot() +
geom_col(aes(x = chrt_grad, y = n, fill = college_enrolled), color = NA) +
geom_text(
aes(x = chrt_grad, y = label_height, label = n),
color = "white"
) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1))) +
labs(x = NULL, y = NULL) +
scale_fill_manual(values = c("#00aeff", "#005488"))
如果我们生成另一个具有不同 n
值范围的数据集——例如,~1200 - ~2000——文本标签保持在相同的相对位置: