ggplot 中从值到颜色的一致映射

Consistent mapping from value to color in ggplot

我想我在这里遗漏了一些非常简单的东西,但我现在想不通: 我想始终如一地将颜色分配给多个图中一列中的某些值。 所以我有这个问题 (sl):

# A tibble: 15 x 3
   class                           hex         x
   <chr>                           <chr>   <int>
 1 translational slide             #c23b22     1
 2 rotational slide                #AFC6CE     2
 3 fast flow-type                  #b7bf5e     3
 4 complex                         #A6CEE3     4
 5 area subject to rockfall/topple #1F78B4     5
 6 fall-type                       #B2DF8A     6
 7 n.d.                            #33A02C     7
 8 NA                              #FB9A99     8
 9 area subject to shallow-slides  #E31A1C     9
10 slow flow-type                  #FDBF6F    10
11 topple                          #FF7F00    11
12 deep-seated movement            #CAB2D6    12
13 subsidence                      #6A3D9A    13
14 areas subject to subsidence     #FFFF99    14
15 area of expansion               #B15928    15

这应该重新创建它:

structure(list(class = c("translational slide", "rotational slide", 
"fast flow-type", "complex", "area subject to rockfall/topple", 
"fall-type", "n.d.", NA, "area subject to shallow-slides", "slow flow-type", 
"topple", "deep-seated movement", "subsidence", "areas subject to subsidence", 
"area of expansion"), hex = c("#c23b22", "#AFC6CE", "#b7bf5e", 
"#A6CEE3", "#1F78B4", "#B2DF8A", "#33A02C", "#FB9A99", "#E31A1C", 
"#FDBF6F", "#FF7F00", "#CAB2D6", "#6A3D9A", "#FFFF99", "#B15928"
), x = 1:15), row.names = c(NA, -15L), class = c("tbl_df", "tbl", 
"data.frame"))

现在我想在每个 class 上绘制一条颜色为 hex-code 的条(现在仅用于可视化目的)。所以我做了:

ggplot(sl) +
  geom_col(aes(x = x,
               y = 1,
               fill = class)) +
  scale_fill_manual(values = sl$hex) +
  geom_text(aes(x = x,
                y = 0.5,
                label = class),
            angle = 90)

但是这些颜色不是小标题中的颜色。 所以我试着按照这个指南:How to assign colors to categorical variables in ggplot2 that have stable mapping? 并创建了这个:

# create the color palette
mycols = sl$hex 
names(mycols) = sl$class

然后用

绘制
ggplot(sl) +
  geom_col(aes(x = x,
               y = 1,
               fill = class)) +
  scale_fill_manual(values = mycols) +
  geom_text(aes(x = x,
                y = 0.5,
                label = class),
            angle = 90)

但是结果是一样的。是这样的:

例如,翻译幻灯片具有十六进制代码:“#c23b22”,应该是柔和的深红色。 任何人都可能知道我在这里缺少什么?

我认为问题在于 scale_fill_manual 期望其 valueslabels 参数的 order 匹配。您的数据集不是这种情况。

sl %>% ggplot() +
  geom_col(aes(x = x,
               y = 1,
               fill = hex)) +
  geom_text(aes(x = x,
                y = 0.5,
                label = class),
            angle = 90) +
  scale_fill_manual(values=sl$hex, labels=sl$class)

给你想要的?

下次请dput()你的测试数据:我创建测试数据集的时间与回答你的问题一样长。此外,对颜色使用十六进制代码使得难以检查颜色是否符合预期。对于 MWE,blue/green/black etx 会更有帮助。

您需要根据您的专栏提供正确的颜色顺序,因为已经有一个名为 'x' 的颜色,我也使用过它。我还用字符 'NA' 替换了 NA。我检查了其中的几个,如果这不是所需的输出,请告诉我。谢谢

#Assuming df is your dataframe:

df[is.na(df$class), 'class'] <- 'NA'

ggplot(df) +
geom_col(aes(x = x,
           y = 1,
           fill = factor(x))) +
scale_fill_manual(values = df$hex, labels=df$class) +
geom_text(aes(x = x,
            y = 0.5,
            label = class),
        angle = 90)

输出:

考虑一下:


sl <- structure(list(class = c("translational slide", "rotational slide",
"fast flow-type", "complex", "area subject to rockfall/topple",
"fall-type", "n.d.", NA, "area subject to shallow-slides", "slow flow-type",
"topple", "deep-seated movement", "subsidence", "areas subject to subsidence",
"area of expansion"), hex = c("#c23b22", "#AFC6CE", "#b7bf5e",
"#A6CEE3", "#1F78B4", "#B2DF8A", "#33A02C", "#FB9A99", "#E31A1C",
"#FDBF6F", "#FF7F00", "#CAB2D6", "#6A3D9A", "#FFFF99", "#B15928"
), x = 1:15), row.names = c(NA, -15L), class = c("tbl_df", "tbl",
"data.frame"))

sl$class <- factor( sl$class, levels=unique(sl$class) )

cl <- sl$hex
names(cl) <- paste( sl$class )

ggplot(sl) +
    geom_col(aes(x = x,
                 y = 1,
                 fill = class)) +
    scale_fill_manual( values = cl, na.value = cl["NA"] ) +
    geom_text(aes(x = x,
                  y = 0.5,
                  label = class),
              angle = 90)

通过将 class 更改为一个因子并为其设置水平,并为 scale_fill_manual 中的值使用命名向量,并在其中正确使用 na.value,您可能会得到看起来更像预期的东西。