【问题标题】:Representing scatter plot data in a Venn diagramatic way?以维恩图的方式表示散点图数据?
【发布时间】:2014-05-08 02:43:12
【问题描述】:

我有几个散点图,代表我数据的不同子集。我想找到一种方法来直观地表示这些数据子集的重叠/缺乏重叠。在 R 或 Matlab 中,将每组数据转换为考虑数据均值和方差的椭圆的最佳方法是什么?如果有意义的话,我基本上想将三个单独的散点图转换为维恩图。

【问题讨论】:

标签: r matlab graph scatter-plot variance


【解决方案1】:

您可以使用 ellipse 包中的 ellipse 函数来计算椭圆上的点,对于每组数据,您可以为椭圆函数提供均值、标准差和相关性,然后将结果传递给 @987654322 @ 函数添加到散点图中。如果组相当正常,这将很有效,但如果组中存在强烈偏斜,则椭圆将无法很好地拟合。

另一种选择是使用chull 函数来计算包含组中所有点的复杂外壳。您可以使用它来绘制一个包含所有点的多边形(有些会接触多边形)。如果你想要比多边形更弯曲的东西,那么使用xspline 函数来绘制而不是linespolygon。下面是一些示例代码:

with(iris, plot( Petal.Width, Petal.Length, col=c('red','green','blue')[Species]))

tmp <- chull(iris[ iris$Species=='setosa', c('Petal.Width','Petal.Length')])
xspline( iris[ iris$Species=='setosa', c('Petal.Width','Petal.Length')][tmp,],
    border='red',open=FALSE, shape= -0.75)

tmp <- chull(iris[ iris$Species=='versicolor', c('Petal.Width','Petal.Length')])
xspline( iris[ iris$Species=='versicolor', c('Petal.Width','Petal.Length')][tmp,],
    border='green',open=FALSE, shape= -0.75)

tmp <- chull(iris[ iris$Species=='virginica', c('Petal.Width','Petal.Length')])
xspline( iris[ iris$Species=='virginica', c('Petal.Width','Petal.Length')][tmp,],
    border='blue',open=FALSE, shape= -0.75)



library(ellipse)

with(iris, plot( Petal.Width, Petal.Length, col=c('red','green','blue')[Species]))

polygon( ellipse( 
    var( iris[ iris$Species=='setosa', c('Petal.Width','Petal.Length') ] ),
    centre=colMeans(iris[ iris$Species=='setosa', c('Petal.Width','Petal.Length') ]),
    t=3),
    border='red')

polygon( ellipse( 
    var( iris[ iris$Species=='versicolor', c('Petal.Width','Petal.Length') ] ),
    centre=colMeans(iris[ iris$Species=='versicolor', c('Petal.Width','Petal.Length') ]),
    t=3),
    border='green')

polygon( ellipse( 
    var( iris[ iris$Species=='virginica', c('Petal.Width','Petal.Length') ] ),
    centre=colMeans(iris[ iris$Species=='virginica', c('Petal.Width','Petal.Length') ]),
    t=3),
    border='blue')

【讨论】:

    【解决方案2】:

    除了@hrbrmstr 链接的问答中给出的解决方案之外,还可以使用凸包来实现它的逐字表示:

    library(scales) #Only for the transparency effect
    data(iris)
    plot(iris$Sepal.Length, iris$Sepal.Width, type="n")
    a <- split(iris, iris$Species) #Separate the dataset by ID (here species)
    for(i in seq_along(a)){
        h <- chull(a[[i]]) #Compute convex hull for each group
        h <- c(h, h[1])
        polygon(a[[i]][h,], col=alpha(i,.5), border=NA) #Plot it
        }
    points(iris$Sepal.Length, iris$Sepal.Width, col=iris$Species, pch=19) #Add data points
    

    【讨论】:

    • 当我对我的数据集尝试此操作时,我收到错误“在 data.matrix(x) 中:强制引入的 NAs”并且生成的凸包看起来很糟糕。有什么想法吗?
    • @user1566200 没有看到你的数据,我真的不知道是什么导致了这个问题。出乎意料的是,我认为这是一个数据类型问题:检查所有应该是数字的内容是否确实是数字,而不是字符串或因子。
    • 谢谢,原来如此。里面有弦。这看起来很漂亮。有没有办法用点()为颜色添加图例?在帮助中的任何地方都看不到它。
    • 看看?legend。基本上在这个例子中你想做类似legend("bottomright", names(a), col=1:3, pch=19).