如何在堆积柱形图上放置不重叠的直接标签?geom_text_repel()
正在移动不需要移动的标签,从而导致可读性问题。
library(tibble)
library(tidyr)
library(ggplot2)
library(ggrepel)
library(dplyr)
library(scales)
set.seed(23)
n <- 4
mu <- 4E6
sales <- tibble(
year=as.factor(seq(2019, length.out=n)),
A = rnorm(n=n, mean=mu, sd=mu/4),
B = rnorm(n=n, mean=6*mu, sd=mu),
C = rnorm(n=n, mean=mu/5, sd=mu/40),
D = rnorm(n=n, mean=mu/10, sd=mu/40),
E = rnorm(n=n, mean=4*mu, sd=mu)
) %>% pivot_longer(!year, names_to="product", values_to="sales")
p <- sales %>%
group_by(year, product) %>%
summarise(sales=sum(sales)) %>%
mutate(pct_of_year_sales = sales/sum(sales),
label=paste(
scales::label_dollar(scale=1/1E6, suffix="M", accuracy=0.1)(sales),
scales::label_percent(accuracy=0.1)(pct_of_year_sales),
sep=", ")) %>%
ggplot(aes(x=year, y=sales, fill=product, label=label)) +
geom_col() +
scale_y_continuous(labels = scales::label_dollar(scale=1/1E6, suffix="M"),
expand = expansion(mult = c(0, .05)))
p + geom_text(position=position_stack(vjust=0.5)) +
labs(title="geom_text()",
subtitle="overlapping labels")
p + geom_text_repel(position=position_stack(vjust = 0.5),
direction="y") +
labs(title="geom_text_repel()",
subtitle="text for series A moves needlessly")
由reprex package(v2.0.1)于2023年2月2日创建
2条答案
按热度按时间deyfvvtc1#
我完全同意@tjebo的评论,有时候添加这么多文本并不是最好的方法。但有时候这是强制性的(我们无法控制),所以我建议解决你的一个抱怨:
geom_text_repel()
正在移动不需要移动的标注我们可以在大多数情况下使用
geom_text
(按销售百分比过滤),在少数情况下使用geom_text_repel
。通常,我会使用
data = ~ filter(., pct_of_year_sales <= 0.015))
(>
用于main),但是当列的数量和值被打乱时,堆叠也会被打乱。相反,我们可以创建两组标签,其中一些是空的(""
或NA
),这取决于它们的pct_of_year_sales
值。这样,geom_text_repel
可以看到所有列/值,并将它们放置在适当的位置。我添加了
hjust=
来稍微移动它们,这也有助于澄清线段线(如果没有hjust
,它们倾向于与逗号连接,这是一个视觉上分散注意力的人工产物)。您可能希望使用force=
或其他线段美学来更清楚地将它们分开。(例如,为了控制每年的水平对齐,可以在框架本身内定义hjust
,而在aes(..)
内指定美学,这只是一个想法。)hvvq6cgz2#
我想我更喜欢@r2evans的答案,因为它利用了工具,因为他们是用来。我走了一条不同的路线。
开始了解电网永远不会太早...
它使用库
grid
和gridExtra
。首先,我将打印保存到对象,并调查标签的位置和应用的设置(使用
geom_text
,而不是...repel
)。在
grid
中,你可以设置每个标签的对齐方式。所以我把C
中的值的垂直对齐方式设置为0,D
中的值的垂直对齐方式设置为1。这在我的绘图窗格中已经足够了......然而,根据图形的大小,你可能需要选择距离更远的值。只要记住.5是中间,而不是0。有关更深入的解释,请参见我的代码注解。
你可以查看带有网格的绘图,或者将它改回
ggplot
对象。要将它改回ggplot对象,你可以使用ggplotify::as.ggplot
或ggpubr::as_ggplot
,它们做同样的事情。