geom_label_repel 的文字颜色

Text color with geom_label_repel

不特定于任何特定代码段,是否有相对直接的方法来更改 geom_label_repel 框中文本的颜色?

具体来说,我有生成下图的代码

标签框中的百分比是最近一周的 7 天移动平均线相对于前一周的百分比变化。我只想在值为正时将文本着色为红色,在值为负时将文本着色为绿色。

可以从 here.

复制此图表的数据框

剧情代码为

#endpoint layer
BaseEndpoints <- smDailyBaseData %>% filter(Base %in% AFMCbases) %>%
  group_by(Base) %>%
  filter(DaysSince == max(DaysSince)) %>%
  select(Base, abbv, DaysSince, newRate,label) %>%
  ungroup()

ZoomEndpoints <- BaseEndpoints %>% filter(Base != 'Edwards') %>%
  mutate(zoom = TRUE)
CAEndPoint <- BaseEndpoints %>% filter(Base == 'Edwards') %>%
  mutate(zoom = FALSE)

ZoomEndpoints <- rbind(ZoomEndpoints, CAEndPoint)

BasePlot <- smDailyBaseData %>% filter(Base %in% AFMCbases) %>%
  ggplot(mapping = aes(x = as.numeric(DaysSince), y = newRate)) +
  geom_line(aes(color=abbv),show.legend = FALSE) +
  scale_color_ucscgb() +
 geom_point(data = BaseEndpoints,size = 1.5,shape = 21, 
            aes(color = abbv,fill = abbv), show.legend = FALSE) +
 geom_label_repel(data=ZoomEndpoints, aes(label=label), show.legend = FALSE,
                   vjust = 0, xlim=c(105,200), size=3, direction='y') +
  labs(x = "Days Since First Confirmed Case", 
       y = "% Local Population Infected Daily") +
  theme(plot.title = element_text(size = rel(1), face = "bold"),
        plot.subtitle = element_text(size = rel(0.7)),
        plot.caption = element_text(size = rel(1))) +
  facet_zoom(xlim = c(50,120), ylim=c(0,0.011),zoom.data=zoom)



print(BasePlot)

是的,就这么简单:

library(ggplot2)

df <- data.frame(x = c(-1, -1, 1, 1), y = c(-1, 1, 1, -1), value = c(-2, -1, 1, 2))

ggplot(df, aes(x, y)) + 
  geom_point(size = 3) +
  ggrepel::geom_label_repel(aes(label = value, colour = factor(sign(value)))) +
  lims(x = c(-100, 100), y = c(-100, 100))  +
  scale_colour_manual(values = c("red", "forestgreen"))


编辑

现在有了更具体的例子,我可以更清楚地看到问题了。有一些解决方法,例如使用 ggnewscale 或手工制作的解决方案,例如 Ian Campbell 的详尽示例。就个人而言,我只是注意到您还没有使用填充比例,这在我看来很不错:

这是一个有点老套的解决方案,因为您不能同时拥有两个 scale_color_*

该方法的核心是在 geom_label_repel 调用中手动分配 aes 之外的颜色。在搜索标签中的减号的 grepl 结果中添加一个,可以让您对两种颜色进行子集化。您需要为每个标签使用两种颜色,我假设用于框和文本,所以我使用了 rep

smDailyBaseData %>% 
ggplot(mapping = aes(x = as.numeric(DaysSince), y = newRate)) +
  geom_line(aes(color=abbv),show.legend = FALSE) +
  scale_color_ucscgb() +
 geom_point(data = BaseEndpoints,size = 1.5,shape = 21, 
            aes(color = abbv,fill = abbv), show.legend = FALSE) +
 geom_label_repel(data=ZoomEndpoints, aes(label=label),
     color = rep(c("green","red")[1+grepl("\-\d",as.factor(ZoomEndpoints$label))],times = 2),
     show.legend = FALSE, vjust = 0, xlim=c(105,200),
     size=3, direction='y') +
 labs(x = "Days Since First Confirmed Case", 
       y = "% Local Population Infected Daily") +
 theme(plot.title = element_text(size = rel(1), face = "bold"),
        plot.subtitle = element_text(size = rel(0.7)),
        plot.caption = element_text(size = rel(1))) +
 facet_zoom(xlim = c(50,120), ylim=c(0,0.011),zoom.data=zoom)

数据设置

#source("https://pastebin.com/raw/Vn2abQ4a")
BaseEndpoints <- smDailyBaseData %>% 
  group_by(Base) %>%
  dplyr::filter(DaysSince == max(DaysSince)) %>%
  dplyr::select(Base, abbv, DaysSince, newRate,label) %>%
  ungroup()
ZoomEndpoints <- BaseEndpoints %>% filter(Base != 'Edwards') %>%
  mutate(zoom = TRUE)
CAEndPoint <- BaseEndpoints %>% filter(Base == 'Edwards') %>%
  mutate(zoom = FALSE)
ZoomEndpoints <- rbind(ZoomEndpoints, CAEndPoint)