plot / ggplot2 - 填充太多点的区域

时间:2016-01-27 10:50:20

标签: r plot ggplot2

最终实施 - 未完成但正确的方式

想法/问题:您有一个包含许多重叠点的绘图,并希望将其替换为普通区域,从而提高了查看绘图的性能。

可能的实施:计算所有点之间的距离矩阵并连接指定距离以下的所有点。

Todo /未完成:此功能目前适用于手动设置的距离,具体取决于打印图的大小。我在这里停了下来,因为结果没有达到我的审美意识。

中间地块的最小例子

set.seed(074079089)
n.points <- 3000

mat <- matrix(rnorm(n.points*2, 0,0.2), nrow=n.points, ncol=2)
colnames(mat) <- c("x", "y")

d.mat <- dist(mat)
fit.mat <-hclust(d.mat, method = "single")
lims <- c(-1,1)
real.lims <- lims*1.1               ## ggplot invokes them approximately

# An attempt to estimate the point-sizes, works for default pdfs pdf("test.pdf")
cutsize <- sum(abs(real.lims))/100  
groups <- cutree(fit.mat, h=cutsize) # cut tree at height cutsize
# plot(fit.mat) # display dendogram

# draw dendogram with red borders around the 5 clusters
# rect.hclust(fit.mat, h=cutsize, border="red")

library(ggplot2)
df <- data.frame(mat)
df$groups <- groups
plot00 <- ggplot(data=df, aes(x,y, col=factor(groups))) + 
    geom_point() + guides(col=FALSE) +  xlim(lims) + ylim(lims)+ 
    ggtitle("Each color is a group")
pdf("plot00.pdf")
print(plot00)
dev.off()

plot00 - points with group color

# If less than 4 points are connected, show them seperately
t.groups <- table(groups)   # how often which group
drop.group <- as.numeric(names(t.groups[t.groups<4]))   # groups with less than 4 points are taken together
groups[groups %in% drop.group] <- 0                     # in group 0
df$groups <- groups
plot01 <- ggplot(data=df, aes(x,y, col=factor(groups))) + 
    geom_point() + xlim(lims)+ ylim(lims) + 
    scale_color_hue(l=10)
pdf("plot01.pdf")
print(plot01)
dev.off()

plot01 - all single points in one group

find_hull <- function(df_0) 
{
    return(df_0[chull(df_0$x, df_0$y), ])
}


library(plyr)
single.points.df <- df[df$groups == 0 , ]
connected.points.df <- df[df$groups != 0 , ]
hulls <- ddply(connected.points.df, "groups", find_hull) #  for all groups find a hull
plot02 <- ggplot() + 
    geom_point(data=single.points.df, aes(x,y, col=factor(groups))) + 
    xlim(lims)+ ylim(lims) + 
    scale_color_hue(l=10)
pdf("plot02.pdf")
print(plot02)
dev.off()

plot02 - only "single"-points (less than 4 connected points)

plot03 <- plot02
for(grp in names(table(hulls$groups)))
{
    plot03 <- plot03 + geom_polygon(data=hulls[hulls$groups==grp, ],
                                    aes(x,y), alpha=0.4)
}
# print(plot03)
plot01 <- plot01 + theme(legend.position="none")
plot03 <- plot03 + theme(legend.position="none")
# multiplot(plot01, plot03, cols=2)
pdf("plot03.pdf")
print(plot03)
dev.off()

plot03 - final

初步问题

我有一个(也许是奇怪的)问题。

在某些情节中,我的分析中有数千个点。为了显示它们,电脑需要相当多的时间,因为有很多点。 此后,这些点中的许多点可以重叠,我有一个填充区域(这很好!)。 为了节省时间/精力显示,只需填充此区域即可自行绘制每个点。

我知道热图等有可能,但这不是我想到的想法。我的想法是这样的:

#plot00: ggplot with many many points and a filled area of points
plot00 <- plot00 + fill.crowded.areas()

# with plot(), I sadly have an idea how to manage it

有什么想法吗?或者这没有人会随时做什么?

# Example code
# install.packages("ggplot2")
library(ggplot2)

n.points <- 10000
mat <- matrix(rexp(n.points*2), nrow=n.points, ncol=2)
colnames(mat) <- c("x", "y")
df <- data.frame(mat)
plot00 <- ggplot(df, aes(x=x, y=y)) + 
    theme_bw()  +                       # white background, grey strips
    geom_point(shape=19)# Aussehen der Punkte

print(plot00)

ggplot2

# NO ggplot2
plot(df, pch=19)

plot

修改
要获得fdetsch提到的密度图(我怎么标记名称?),有一些关于这个主题的问题。但这不是我想要的东西。我知道我的担心有点奇怪,但密度使得情节有时会更加繁忙。

与密度主题的链接:

Scatterplot with too many points
High Density Scatter Plots

3 个答案:

答案 0 :(得分:4)

如何使用格子中的panel.smoothScatter?它在低密度区域显示一定数量的点(参见参数&#39; nrpoints&#39;)和其他任何地方,显示点密度而不是单个(可能重叠)点,从而为您的数据提供更有意义的见解。有关详细信息,另请参阅?panel.smoothScatter

## load 'lattice'
library(lattice)

## display point densities
xyplot(y ~ x, data = df, panel = function(x, y, ...) {
  panel.smoothScatter(x, y, nbin = 250, ...)
})

enter image description here

答案 1 :(得分:1)

你的意思是convex hull你的观点:

Convex Hull of points

set.seed(1337)
n.points <- 100
mat <- matrix(rexp(n.points*2), nrow=n.points, ncol=2)
colnames(mat) <- c("x", "y")
df <- data.frame(mat)
ch <- chull(df$x, df$y) # This computes the convex hull

require(ggplot2)
ggplot() + 
  geom_point(data=df, aes(x,y)) +
  geom_polygon(data = df[ch,], aes(x,y), alpha=0.5)

答案 2 :(得分:1)

您可以使用强大的估算器估算大部分点的位置,并绘制点的凸包,如下所示:

set.seed(1337)
n.points <- 500
mat <- matrix(rexp(n.points*2), nrow=n.points, ncol=2)
colnames(mat) <- c("x", "y")
df <- data.frame(mat)

require(robustbase)
my_poly <- function(data, a, ...){
  cov_rob = covMcd(data, alpha = a)
  df_rob = data[cov_rob$best,]
  ch = chull(df_rob$x, df_rob$y)
  geom_polygon(data = df_rob[ch,], aes(x,y), ...)
}

require(ggplot2)
ggplot() + 
  geom_point(data=df, aes(x,y)) +
  my_poly(df, a = 0.5, fill=2, alpha=0.5) +
  my_poly(df, a = 0.7, fill=3, alpha=0.5) 

这导致:

enter image description here

通过控制covMcd的alpha值,您可以增加/减少区域的大小。有关详细信息,请参阅?robustbase::covMcd。 顺便说一句:Mcd代表最小协方差行列式。您也可以使用MASS::cov.mve计算MASS::cov.mve(..., quantile.used=的最小值的椭球,而不是椭圆体中的点数百分比。

2个以上的课程:

my_poly2 <- function(data, a){
  cov_rob = covMcd(data, alpha = a)
  df_rob = data[cov_rob$best,]
  ch = chull(df_rob[,1], df_rob[,2])
  df_rob[ch,]
}

ggplot(faithful, aes(waiting, eruptions, color = eruptions > 3)) +
  geom_point() + 
  geom_polygon(data = my_poly2(faithful[faithful$eruptions > 3,], a=0.5), aes(waiting, eruptions), fill = 2, alpha = 0.5) +
  geom_polygon(data = my_poly2(faithful[faithful$eruptions < 3,], a=0.5), aes(waiting, eruptions), fill = 3, alpha = 0.5)

enter image description here

或者,如果您对不稳定的椭圆体没问题,请查看stat_ellipse