如何为ggplot2中具有稳定映射的分类变量赋值?

win*_*our 159 r ggplot2

我在上个月一直在加快速度.

这是我的问题:

将颜色分配给ggplot2中具有稳定映射的分类变量的好方法是什么?我需要在一组图表中具有一致的颜色,这些图表具有不同的子集和不同数量的分类变量.

例如,

plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line()
Run Code Online (Sandbox Code Playgroud)

哪里categoricalData有5个级别.

然后

plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset, 
                                 color=categoricaldData.subset)) + geom_line()
Run Code Online (Sandbox Code Playgroud)

哪里categoricalData.subset有3个级别.

但是,两组中的特定级别将以不同的颜色结束,这使得更难以一起阅读图形.

我是否需要在数据框中创建颜色矢量?或者是否有另一种方法可以为类别指定特定颜色?

jor*_*ran 172

对于像OP中的确切示例这样的简单情况,我同意Thierry的答案是最好的.但是,我认为指出另一种方法变得更容易,当您尝试在多个数据帧中维护一致的颜色方案时,这些方法不是通过对单个大数据帧进行子集化获得的.如果从单独的文件中提取多个数据框中的因子级别并且并非所有因子级别都出现在每个文件中,则可能会变得单调乏味.

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

#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)
Run Code Online (Sandbox Code Playgroud)

然后根据需要将颜色比例添加到绘图中:

#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
Run Code Online (Sandbox Code Playgroud)

第一个情节看起来像这样:

在此输入图像描述

第二个情节看起来像这样:

在此输入图像描述

这样,您无需记住或检查每个数据框,以确定它们具有适当的级别.

  • @Andrie - 对于一个子集,是的.但是,如果您正在处理大量数据集,这些数据集并非都是通过对一个原始数据框进行子集化而创建的,那么我发现这种策略更加简单. (12认同)
  • 工作完美!我添加了`fillScale < - scale_fill_manual(name ="grp",values = myColors)`来使用条形图. (4认同)
  • 我需要:库("RColorBrewer") (3认同)
  • @joran谢谢Joran。这对我有用!它创建了具有正确数量的因子的图例。我喜欢这种方法,并且获得跨不同数据集的颜色映射非常值得三行。 (2认同)

Ale*_*son 38

我在相同的情况下所指出的malcook他的评论:不幸的是,答案蒂埃里不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()
Run Code Online (Sandbox Code Playgroud)

这是第一个数字:

ggplot AE,混合色

和第二个数字:

ggplot ADE,混色

我们可以看到颜色不会保持固定,例如E从品红色切换到蓝色.

正如malcook他的评论hadley他的评论中所建议的那样,使用的代码limits正常工作:

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

给出下图,这是正确的:

正确的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 
Run Code Online (Sandbox Code Playgroud)

  • 您应该将此作为一个新问题发布,引用此问题并说明为什么此处的解决方案不起作用. (3认同)

Thi*_*rry 20

最简单的解决方案是将分类变量转换为子集之前的因子.底线是您需要一个因子变量,在所有子集中具有完全相同的级别.

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"))
Run Code Online (Sandbox Code Playgroud)

带有字符变量

ggplot(dataset, aes(x = x, y = y, colour = category)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = category)) + geom_point()
Run Code Online (Sandbox Code Playgroud)

使用因子变量

ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()
Run Code Online (Sandbox Code Playgroud)

  • 最简单的方法是使用限制 (11认同)
  • @Thierry - 在我手中,使用ggplot2_0.9.3.1,这种方法不再(不再?)工作; 分配给fCategory的颜色在两个图之间是不同的.然而,愉快地,@ wintour,我认为@hadley建议`+ scale_colour_discrete(drop = TRUE,limits = levels(dataset $ fCategory))`来保留颜色|因子关联但是,除了在我手中之外,[drop = TRUE](http://docs.ggplot2.org/current/discrete_scale.html)不被尊重(我希望它从图例中删除级别).Drat ......还是我? (11认同)
  • 可以在这方面提供一个例子哈德利吗?我不确定如何使用一个因素的限制。 (2认同)
  • @malcook,而不是 drop = TRUE,您需要通过“中断”指定要保留的级别:https://github.com/hadley/ggplot2/issues/1433 (2认同)

Mar*_*ian 15

根据joran非常有用的答案,我能够为布尔因子(TRUE,FALSE)提供稳定色标的解决方案.

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
Run Code Online (Sandbox Code Playgroud)

由于ColorBrewer对二进制色标没有多大帮助,因此手动定义了所需的两种颜色.

以下mybooleanmyDataFrame保持TRUE/FALSE因子的列的名称.date并且duration是在此示例中要映射到绘图的x和y轴的列名称.


Pav*_*dis 9

这是一篇旧文章,但我一直在寻找相同问题的答案,

为什么不尝试这样的事情:

scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00"))
Run Code Online (Sandbox Code Playgroud)

如果您具有绝对值,我看不出为什么这不起作用的原因。

  • 这实际上是 Joran 的回答所做的,但使用 `myColors &lt;- brewer.pal(5,"Set1"); names(myColors) &lt;- levels(dat$grp)` 以避免必须手动编码级别。 (5认同)
  • 但是,Joran 的回答并没有硬编码颜色的值。在某些情况下,您需要给定因子的特定颜色值。 (2认同)