geom_label_repel() 标签不在正确的点上

问题描述 投票:0回答:1

我正在使用

ggplot2
来绘制一些图来表示 Likert 量表数据,并且需要排斥一些标签,但不需要排斥其他标签。根据 StackOverflow 上找到的大量答案,我想出了以下代码,但排斥的标签位于绘图上的错误位置。

#### Minimum Working Dataset
### Data Creation
## Initial Tibble
survey <- tibble(
  question_n = 1,
  answer = c("Somewhat Agree", "Somewhat Disagree", "Strongly Agree", "Strongly Disagree"),
  n = c(90, 12, 199, 4),
  respondents = 305,
  pct = n / respondents
)

## Factor levels for answers
survey$answer <- factor(survey$answer,
                        levels = c("Strongly Agree", "Somewhat Agree",
                                   "Somewhat Disagree", "Strongly Disagree"))

从这里开始,创建就足够简单了:

ggplot

Initial ggplot without ggrepel 显然,这需要一个

### Plot survey %>% ggplot(aes(x = pct, y = 1, fill = fct_rev(answer))) + geom_col(color = "black") + theme_minimal() + scale_x_continuous(labels = label_percent(), # Expand so the labels aren't off-plot expand = expansion(mult = c(0.025, 0.025))) + scale_y_discrete(labels = NULL) + geom_label(aes(label = percent_format(accuracy = 1)(pct), color = fct_rev(answer)), fill = "white", size = 3.25, fontface = "bold", label.size = 1, label.r = unit(2.5, "pt"), show.legend = FALSE, position = position_stack(vjust = 0.5, reverse = FALSE),) + scale_fill_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4")) + scale_color_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4"), guide = "none") + guides(fill = guide_legend(position = "bottom", nrow = 2, reverse = TRUE)) + labs( title = NULL, subtitle = NULL, caption = paste("Respondents N =", survey[1,]$respondents), fill = NULL, color = NULL, x = NULL, y = NULL )

! “不同意”响应标签相互重叠。所以,我把

geom_label_repel()
改为
geom_label()
geom_label_repel()

ggplot with the ggrepel

技术上

可行,但看起来真的很乱。 65%和30%的结果被驳回了,尽管没有必要这样做。所以,最后,我尝试包括两者### Plot survey %>% ggplot(aes(x = pct, y = 1, fill = fct_rev(answer))) + geom_col(color = "black") + theme_minimal() + scale_x_continuous(labels = label_percent(), # Expand so the labels aren't off-plot expand = expansion(mult = c(0.025, 0.025))) + scale_y_discrete(labels = NULL) + geom_label_repel(aes(label = percent_format(accuracy = 1)(pct), color = fct_rev(answer)), # Filter data to only less than 5.5% for repel; labels fit otherwise # data = . %>% filter(pct < 0.055), fill = "white", size = 3.25, fontface = "bold", label.size = 1, label.r = unit(2.5, "pt"), show.legend = FALSE, position = position_stack(vjust = 0.5, reverse = FALSE), # Set direction so that repel is only "up" or "down" on plot direction = "y", # Set ylim to prevent labels going off the bar ylim = c(.6, 1.3), # Set seed so they always place in same position seed = 12345 ) + scale_fill_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4")) + scale_color_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4"), guide = "none") + guides(fill = guide_legend(position = "bottom", nrow = 2, reverse = TRUE)) + labs( title = NULL, subtitle = NULL, caption = paste("Respondents N =", survey[1,]$respondents), fill = NULL, color = NULL, x = NULL, y = NULL )

geom_label()
geom_label_repel()

Both geom_label and geom_label_repel 因此,65% 和 30% 处于正确的位置,但 4% 和 1% 现在处于错误的 x 位置。我尝试了一些方法来调整它,例如向

### Plot survey %>% ggplot(aes(x = pct, y = 1, fill = fct_rev(answer))) + geom_col(color = "black") + theme_minimal() + scale_x_continuous(labels = label_percent(), # Expand so the labels aren't off-plot expand = expansion(mult = c(0.025, 0.025))) + scale_y_discrete(labels = NULL) + geom_label_repel(aes(label = percent_format(accuracy = 1)(pct), color = fct_rev(answer)), # Filter data to only less than 5.5% for repel; labels fit otherwise data = . %>% filter(pct < 0.055), fill = "white", size = 3.25, fontface = "bold", label.size = 1, label.r = unit(2.5, "pt"), show.legend = FALSE, position = position_stack(vjust = 0.5, reverse = FALSE), # Set direction so that repel is only "up" or "down" on plot direction = "y", # Set ylim to prevent labels going off the bar ylim = c(.6, 1.3), # Set seed so they always place in same position seed = 12345 ) + geom_label(aes(label = percent_format(accuracy = 1)(pct), color = fct_rev(answer)), # Filter data to everything greater than 5.5%; no need to repel these items data = . %>% filter(pct >= 0.055), fill = "white", size = 3.25, fontface = "bold", label.size = 1, label.r = unit(2.5, "pt"), show.legend = FALSE, position = position_stack(vjust = 0.5, reverse = FALSE),) + scale_fill_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4")) + scale_color_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4"), guide = "none") + guides(fill = guide_legend(position = "bottom", nrow = 2, reverse = TRUE)) + labs( title = NULL, subtitle = NULL, caption = paste("Respondents N =", survey[1,]$respondents), fill = NULL, color = NULL, x = NULL, y = NULL )

添加

x = 
值,指定
aes()
位置而不是
nudge_x = 
,以及其他一些我现在实际上记不起的东西。在过去的几个小时里我一直在努力解决这个问题。
我需要 65% 和 30% 的位置,以及其他两个值,它们应该位于一个轴上,并像在另一个轴上一样进行微调。有什么建议吗?

r ggplot2 plot ggrepel
1个回答
0
投票
position_stack()

包,它具有一些有用的位置函数,在本例中为

ggpp
,正如您所猜测的,它允许数据堆叠和微移。
但首先您需要按问题和答案排列数据,以控制微移距离需要“

长度为1的数字向量,或者与数据中的行长度相同,微移值按数据行顺序排列。

接下来,识别连续值低于特定阈值的实例,并使用交替符号分配微移偏移值。

您必须根据绘图的宽度和高度修改阈值和偏移值。

使用您的示例数据:

position_stacknudge()

enter image description here 扩展绘制多个问题需要调整偏移值:

library(ggplot2) library(ggpp) library(scales) library(dplyr) survey <- tibble( question_n = 1, answer = c("Somewhat Agree", "Somewhat Disagree", "Strongly Agree", "Strongly Disagree"), n = c(90, 12, 199, 4), respondents = 305, pct = n / respondents ) survey$answer <- factor(survey$answer, levels = c("Strongly Agree", "Somewhat Agree", "Somewhat Disagree", "Strongly Disagree")) threshold <- .06 off_y <- .1 survey <- survey %>% arrange(question_n, answer) %>% mutate(flag = pct <= threshold, cid = consecutive_id(flag), .by = question_n) %>% mutate(offset = if_else(flag & n() > 1, off_y * -cospi(row_number()), 0), .by = c(question_n, cid)) survey %>% ggplot(aes(x = pct, y = question_n, fill = fct_rev(answer))) + geom_col(color = "black") + theme_minimal() + scale_x_continuous(labels = label_percent(), # Expand so the labels aren't off-plot expand = expansion(mult = c(0.025, 0.025))) + scale_y_discrete(labels = NULL) + geom_label(aes(label = percent_format(accuracy = 1)(pct), color = fct_rev(answer)), fill = "white", size = 3.25, fontface = "bold", label.size = 1, label.r = unit(2.5, "pt"), show.legend = FALSE, position = position_stacknudge(vjust = 0.5, y = survey$offset, reverse = FALSE),) + scale_fill_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4")) + scale_color_manual(values = c("tomato4", "tomato", "royalblue", "royalblue4"), guide = "none") + guides(fill = guide_legend(position = "bottom", nrow = 2, reverse = TRUE)) + labs( title = NULL, subtitle = NULL, caption = paste("Respondents N =", survey$respondents[1]), fill = NULL, color = NULL, x = NULL, y = NULL )

如上绘图给出:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.