如何将颜色分配给ggplot2中具有稳定映射的类别变量?

上个月我一直在学习R。

我的问题是:

为ggplot2中具有稳定映射的类别变量分配颜色的好方法是什么?我需要在一组具有不同子集和不同数量分类变量的图中保持一致的颜色。

例如,

plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line()

其中categoricalData有5个级别。

然后

plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset,
color=categoricaldData.subset)) + geom_line()

其中categoricalData.subset有3层。

然而,两个集合中的特定水平最终将使用不同的颜色,这使得很难一起阅读图表。

我需要在数据帧中创建一个颜色向量吗?或者还有其他方法为类别分配特定的颜色吗?

284746 次浏览

对于简单的情况,比如OP中的确切例子,我同意蒂埃里的答案是最好的。然而,我认为指出另一种更容易的方法是有用的,当你试图在多个数据帧之间保持一致的配色方案时,这些数据帧都是,都是通过子集设置单个大数据帧获得的。如果从不同的文件中提取多个数据帧中的因素级别,并且不是每个文件中都出现所有因素级别,那么管理多个数据帧中的因素级别会变得乏味。

解决这个问题的一种方法是创建一个自定义的手动色标,如下所示:

#Some test data
dat <- data.frame(x=runif(10),y=runif(10),
grp = rep(LETTERS[1:5],each = 2),stringsAsFactors = TRUE)


#Create a custom color scale
library(RColorBrewer)
myColors <- brewer.pal(5,"Set1")
names(myColors) <- levels(dat$grp)
colScale <- scale_colour_manual(name = "grp",values = myColors)

然后根据需要在图上添加颜色刻度:

#One plot with all the data
p <- ggplot(dat,aes(x,y,colour = grp)) + geom_point()
p1 <- p + colScale


#A second plot with only four of the levels
p2 <- p %+% droplevels(subset(dat[4:10,])) + colScale

第一个图是这样的:

enter image description here

第二个图是这样的:

enter image description here

这样,您就不需要记住或检查每个数据帧来查看它们是否具有适当的级别。

最简单的解决方案是将分类变量转换为子集设置之前的因子。最重要的是,你需要一个在所有子集中具有完全相同水平的因子变量。

library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100),
x = rnorm(500, mean = rep(1:5, 100)), y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))

使用字符变量

ggplot(dataset, aes(x = x, y = y, colour = category)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = category)) + geom_point()

有一个因子变量

ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()

我处于malcook他的评论中指出的相同情况:不幸的是,回答 by 亨利不适用于ggplot2 0.9.3.1版本。

png("figure_%d.png")
set.seed(2014)
library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100),
x = rnorm(500, mean = rep(1:5, 100)),
y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))


ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()

这是第一个图:

ggplot A-E, mixed colors

第二幅图:

ggplot ADE, mixed colors

正如我们所看到的,颜色不会保持固定,例如E从品红切换到蓝色。

正如他的评论中的malcook他的评论中的哈德利所建议的,使用limits的代码可以正常工作:

ggplot(subdata, aes(x = x, y = y, colour = fCategory)) +
geom_point() +
scale_colour_discrete(drop=TRUE,
limits = levels(dataset$fCategory))

给出如下图,是正确的:

correct ggplot

这是sessionInfo()的输出:

R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)


locale:
[1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8       LC_NAME=C
[9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C


attached base packages:
[1] methods   stats     graphics  grDevices utils     datasets  base


other attached packages:
[1] ggplot2_0.9.3.1


loaded via a namespace (and not attached):
[1] colorspace_1.2-4   dichromat_2.0-0    digest_0.6.4       grid_3.0.2
[5] gtable_0.1.2       labeling_0.2       MASS_7.3-29        munsell_0.4.2
[9] plyr_1.8           proto_0.3-10       RColorBrewer_1.0-5 reshape2_1.2.2
[13] scales_0.2.3       stringr_0.6.2

基于joran非常有用的回答,我能够提出这个解决方案,为布尔因子(TRUEFALSE)提供稳定的颜色刻度。

boolColors <- as.character(c("TRUE"="#5aae61", "FALSE"="#7b3294"))
boolScale <- scale_colour_manual(name="myboolean", values=boolColors)


ggplot(myDataFrame, aes(date, duration)) +
geom_point(aes(colour = myboolean)) +
boolScale

由于ColorBrewer对二进制颜色刻度不是很有帮助,所以需要手动定义两种颜色。

这里mybooleanmyDataFrame中包含TRUE/FALSE因子的列的名称。在本例中,dateduration是要映射到绘图的x轴和y轴的列名。

这是一个老帖子,但我一直在寻找这个问题的答案,

为什么不试试这样的方法呢:

scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00"))

如果你有分类值,我看不出有什么理由不这样做。