ggplot如何动态改变x轴标签颜色

3

以下是测试代码:

library(tidyverse)

df<- data.frame(PCP = c("BOB","FRED","ED","Other"),
                closed = c(42,64,45,1812), 
                total= c(53,81,58,3188), 
                percentage = c(.7924,.7901,.7758,.5683),
                row= c(1, 2, 3,4),
                color =c("0099FF","#CCCCCC","#CCCCCC","#660033"),
                color_fill = c("99","0","0","98"
                ))

col  <- c(
  "99" = "#0099FF",
  "98" = "#660033", 
  "0" = "#CCCCCC" 
)

df %>%  
  arrange(desc(percentage)) %>% 
  mutate(PCP = PCP,
         closed = closed,
         total = total,
         percentage = percentage,
         row = row,
         color = color,
         color_fill = color_fill) -> df1

ggplot(df1,aes(x=PCP, y = percentage,fill=color_fill, color = color)) +
  geom_col() +
  coord_flip() +
  labs(x ="PCP Name",
       y = "Percentage of Gap Closures",
       title =  "TOP 10 PCPs")+
   scale_fill_manual(values = col)+
  scale_color_manual(values = col) +
  scale_y_continuous(labels = percent_format(), limits=c(0,1))+
  theme(legend.position = "none",
        panel.grid = element_blank(),
        panel.background = element_blank(),
        text = element_text(size=15),
        plot.caption = element_text(hjust = 0, face= "italic"),
        axis.text.y = element_text(colour = col ))

我的目标是将x轴标签与条形颜色匹配。
我尝试了以下解决方案: Matching axis.text labels to colors contained in data frame variable in ggplot, 然而,当我尝试因子水平部分时,会出现错误,因为我的实际数据包含其他使用相同的#CCCCCC颜色码的值。
下面是所附代码的输出: Results 我做错了什么吗?

之前有一个答案发布了,我设法在它被删除之前复制和粘贴了。该代码与列出的4个名称配合使用效果很好,但是一旦我添加了其他名称,颜色编码就又不对了。看起来是朝着正确方向迈出的一步,我不再出现多个酒红色或蓝色。 - CCP
2个回答

3
我不是完全确定问题出在哪里(我的意思是,我知道您提供的颜色顺序是错误的;在主题中,您必须使用col[as.integer(df$color)]来模拟因子的顺序,但我不知道为什么),但我有一个有效的解决方法。 ggplot2中不太常用的函数之一是ggplot_build。使用它,您可以像名称所示的那样构建图形,这意味着您可以从中提取所需的值。基于此,我编写了一个小函数,可以实现您想要的功能。
axis_text_color <- function(plot, col = "fill") {
  c <- ggplot_build(plot)$data[[1]]
  plot +
    theme(axis.text.y = element_text(colour = c[[col]]))
}

使用方法是先将图表保存在一个对象中:

library(tidyverse)
plot <- ggplot(df, aes(
    x = PCP,
    y = percentage,
    fill = color_fill,
    color = color
  )) +
  geom_col() +
  coord_flip() +
  labs(x = "PCP Name",
       y = "Percentage of Gap Closures",
       title =  "TOP 10 PCPs") +
  scale_fill_manual(values = col) +
  scale_color_manual(values = col) +
  scale_y_continuous(labels = scales::percent_format(), limits = c(0, 1)) +
  theme(
    legend.position = "none",
    panel.grid = element_blank(),
    panel.background = element_blank(),
    text = element_text(size = 15),
    plot.caption = element_text(hjust = 0, face = "italic")
  )

然后在该图上调用该函数:
axis_text_color(plot)

reprex包(v0.3.0)于2020年01月20日创建


1
这个工作得非常好!非常感谢,你刚刚拯救了我免于陷入疯狂哈哈 @JBGruber - CCP
1
ggplot2 中的因子经常让我感到烦恼。就在写完之后,我发现了另一种解决方法。在主题中,使用 col[as.integer(df$color)] 将 col 向量按与因子 df$color 相同的顺序排序。但是请随意使用该函数! - JBGruber
我尝试了第二种解决方案,但还是有些问题。我会坚持使用你提供的第一种方法。再次感谢!@JBGruber - CCP
1
我意识到我重命名了df。根据原始示例,应该是 col[as.integer(df1$color)]... - JBGruber

0
如果可能的话,请从您的df中删除color,以便不会与您的col向量重复。
您需要根据PCP(基于因子,按字母顺序排序)对color_fill进行排序。
最后,使用as.character创建字符向量而不是因子,并将其用作col的查找参考。
library(tidyverse)
library(scales)

df<- data.frame(PCP = c("BOB","FRED","ED", "Alfred", "Other"),
                closed = c(42,64,45,100,1812), 
                total= c(53,81,58,100,3188), 
                percentage = c(.7924,.7901,.7758,.3,.5683),
                row= c(1,2,3,4,5),
                #color =c("0099FF","#CCCCCC","#CCCCCC", "#00EE00", "#660033"),
                color_fill = c("99","0","0","97","98")
                )

col  <- c(
  "99" = "#0099FF",
  "98" = "#660033", 
  "97" = "#00FF00",
  "0" = "#CCCCCC" 
)

ggplot(df,aes(x=PCP, y=percentage, fill=color_fill, color = color_fill)) +
  geom_col() +
  coord_flip() +
  labs(x ="PCP Name",
       y = "Percentage of Gap Closures",
       title =  "TOP 10 PCPs")+
  scale_fill_manual(values = col)+
  scale_color_manual(values = col)+
  scale_y_continuous(labels = percent_format(), limits=c(0,1))+
  theme(legend.position = "none",
        panel.grid = element_blank(),
        panel.background = element_blank(),
        text = element_text(size=15),
        plot.caption = element_text(hjust = 0, face= "italic"),
        axis.text.y = element_text(colour = col[as.character(df$color_fill[order(df$PCP)])]))

plot with text label color matching bars


抱歉之前删除了。希望这仍然有所帮助。 - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接