在R中按因素对绘图进行着色

49

我正在制作两个变量的散点图,并希望通过一个因子变量来给点着色。以下是一些可再现的代码:

data <- iris
plot(data$Sepal.Length, data$Sepal.Width, col=data$Species)

这些都很好,但我怎么知道哪个因素被着了什么颜色?


2
也许library(ggplot2); qplot(Sepal.Length, Sepal.Width, data=iris, colour=Species)会有所帮助。 - Ben Bolker
抱歉,在回答时没有看到你的评论。 - Matt Bannert
没问题,我太懒/匆忙了,没有好好回答。 - Ben Bolker
6个回答

59
data<-iris
plot(data$Sepal.Length, data$Sepal.Width, col=data$Species)
legend(7,4.3,unique(data$Species),col=1:length(data$Species),pch=1)

这应该对你有所帮助。但我更喜欢ggplot2,建议在R中使用它以获得更好的图形效果。


41
将“更好的图形在R中使用ggplot2”这一建议视为正确的是不正确的。标准的R绘图函数具有更大的潜力。 - Federico Giorgi
3
您好,我想指出设置图例颜色的方法可能会混淆它们。最好使用约翰评论中提到的方法。调用“levels”而不是“unique”来获取因子可能的值。 - eleanorahowe
你的答案对我有用,但是你如何使用ggplot2实现相同的结果呢? - thomasrive
2
使用此方法时要非常小心,因为颜色通常不是使用此代码的正确物种。您真的需要先添加一个物种编号列,然后根据感兴趣的变量对数据框进行排序,然后绘制并引用该物种编号以获取颜色。或者,如果它是一个因子,请像其他人提到的那样使用levels()。 - Adam Erickson
有人能提供一个示例,说明当答案中的代码混淆图例颜色时的情况吗?这样我就可以更好地理解这个问题了。我尝试创建了一个示例,但失败了。我真正想知道的是levels()如何帮助我们解决这个问题。我应该发布我的请求作为一个单独的问题,并参考这个问题吗? - Anton
我将我的问题作为一个单独的问题发布在这里。链接 - Anton

44

palette命令可以告诉你在使用col = somefactor时颜色及其顺序,它也可以用来设置颜色。

palette()
[1] "black"   "red"     "green3"  "blue"    "cyan"    "magenta" "yellow"  "gray"   
为了在您的图表中看到这一点,您可以使用一个图例。
legend('topright', legend = levels(iris$Species), col = 1:3, cex = 0.8, pch = 1)

你会注意到我只用了3个数字来指定新的颜色。这就像使用一个因子一样。我本来可以使用最初用于点颜色的那个因子。这将使一切逻辑上更加连贯...但我只是想展示您可以使用各种各样的东西。

你也可以具体说明颜色。从 ?rainbow 开始尝试并继续下去。你可以指定自己的颜色或让 R 为你选择。只要对每个使用相同的方法,就没问题。


22

我知道两种方法可以按因子对绘图点进行着色,并自动生成相应的图例。下面是两种方法的示例:

  1. 使用ggplot2(通常更容易)
  2. 结合R内置的绘图功能和colorRampPallete函数使用(会有一些技巧,但许多人喜欢/需要使用R的内置绘图工具)

对于这两个示例,我将使用ggplot2中的diamonds数据集。我们将使用数值列diamond$caratdiamond$price,以及因子/分类列diamond$color。如果您安装了ggplot2,可以使用以下代码加载数据集:

library(ggplot2)
data(diamonds)

使用ggplot2和qplot

这是一行代码。关键是将你要按颜色分类的因子作为color参数提供给qplotqplot会默认为您创建图例。

qplot(
  x = carat,
  y = price,
  data = diamonds,
  color = diamonds$color # color by factor color (I know, confusing)
)

您的输出应该像这样:按钻石颜色分类上色的qplot输出

使用R内置的绘图功能

使用R内置的绘图功能来得到一个按因素上色和相应图例的图形是一个四步过程,比使用ggplot2技术稍微复杂一些。

首先,我们将创建一个colorRampPallete函数。colorRampPallete()返回一个新函数,用于生成颜色列表。在下面的代码片段中,调用color_pallet_function(5)会返回一个由5种颜色组成的列表,这些颜色从红色到橙色再到蓝色的范围内:

color_pallete_function <- colorRampPalette(
  colors = c("red", "orange", "blue"),
  space = "Lab" # Option used when colors do not represent a quantitative scale
  )

接下来,我们需要列出颜色列表,每个钻石颜色对应一个颜色。这是我们将用于为各个绘图点分配颜色以及创建图例的映射。

num_colors <- nlevels(diamonds$color)
diamond_color_colors <- color_pallet_function(num_colors)
第三步,我们创建图形。这与您可能已经完成的任何其他绘图相同,只是我们将我们制作的颜色列表称为col参数。只要我们始终使用相同的列表,我们在钻石数据集(diamond$colors)和颜色之间的映射将在我们的R脚本中保持一致。
plot(
  x = diamonds$carat,
  y = diamonds$price,
  xlab = "Carat",
  ylab = "Price",
  pch = 20, # solid dots increase the readability of this data plot
  col = diamond_color_colors[diamonds$color]
)

第四步,最后一步,我们添加图例,以便阅读我们的图表的人可以清楚地看到绘图点颜色与实际钻石颜色之间的映射关系。

legend(
  x ="topleft",
  legend = paste("Color", levels(diamonds$color)), # for readability of legend
  col = diamond_color_colors,
  pch = 19, # same as pch=20, just smaller
  cex = .7 # scale the legend to look attractively sized
)

你的输出应该像这样: 标准的 R 绘图,按因子“diamond$color”着色

不错,对吧?


20

和Maiasaura一样,我更喜欢ggplot2。其中一个原因是它有易于理解的文档。然而,下面这种方法可以快速完成。

require(ggplot2)
data(diamonds)
qplot(carat, price, data = diamonds, colour = color)
# example taken from Hadley's ggplot2 book

因为有名人说过,与情节相关的帖子没有情节就不完整,这是结果:

enter image description here

以下是几个参考资料: qplot.R示例, 请注意,基本上使用了我使用的相同的钻石数据集,但在之前裁剪数据以获得更好的性能。

http://ggplot2.org/book/ 手册:http://docs.ggplot2.org/current/


1
如下所指出,原始数据存在重叠点,因此使用 stat_sum 很方便,例如:ggplot(iris,aes(Sepal.Length,Sepal.Width,colour=Species))+ stat_sum(alpha=0.5,aes(size=factor(..n..))) - Ben Bolker

17

plot 函数中的 col 参数会自动为整数向量赋予颜色。如果你将 iris$Species 转换为数字,你会发现它是一个由 1、2 和 3 组成的向量,因此你可以这样应用:

plot(iris$Sepal.Length, iris$Sepal.Width, col=as.numeric(iris$Species))

如果你想要红色、蓝色和绿色而不是默认颜色,那么你可以简单地进行调整:

plot(iris$Sepal.Length, iris$Sepal.Width, col=c('red', 'blue', 'green')[as.numeric(iris$Species)])

你可能可以看到如何进一步修改上面的代码以获取任何独特的颜色组合。


13

lattice库是另一个不错的选择。在这里,我在右侧添加了图例并且对点进行了微调,因为其中一些点重叠在一起。

xyplot(Sepal.Width ~ Sepal.Length, group=Species, data=iris, 
       auto.key=list(space="right"), 
       jitter.x=TRUE, jitter.y=TRUE)

示例图


2
+1 对于 lattice。当像这样被问问题时,我经常会太自动化 = ggplot。 - Matt Bannert

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