2016-01-27 3 views
6

Окончательной реализации - не закончен, но заголовок правильного путиучастка/ggplot2 - Залейте область со слишком большим количеством точек

Idea/Проблема: У вас есть сюжет с множеством перекрывающихся точек и хотите заменить их равную площадь, что увеличивает производительность просмотра сюжета.

Возможная реализация: Рассчитать матрицу расстояний между всеми точками и соединить все точки ниже указанного расстояния.

Todo/Not finished: В настоящее время это работает для заданных вручную расстояний в зависимости от размера печатного участка. Я остановился здесь, потому что результат не соответствовал моему эстетическому смыслу.

Минимальный пример с промежуточными участками

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

Initial Вопрос

У меня есть (может быть нечетным) вопрос.

На некоторых участках у меня есть тысячи точек в моем анализе. Чтобы отобразить их, компьютер занимает довольно много времени, потому что их так много. После этого многие из этих точек могут перекрываться, у меня есть заполненная область (это нормально!). Чтобы сэкономить время и усилия, было бы полезно просто заполнить эту область, но построение каждой точки само по себе.

Я знаю, что есть возможности в тепловых картах и ​​т. Д., Но это не идея, которую я имею в виду. Моя идея что-то вроде:

#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

Edit:
Чтобы иметь плотности участков, как упомянуто fdetsch (как я могу отметить имя?) Есть некоторые вопросы, касающиеся этого тема. Но это не то, что я хочу точно. Я знаю, что мое беспокойство немного странно, но плотности делают сюжет более занятым, когда это необходимо.

Ссылки на темы с плотностью:

Scatterplot with too many points
High Density Scatter Plots

+0

То, что вы просите, потому что трудно Рендеринг сплошной блок зависит от выбранных вами графических параметров (например, размера точек). Чтобы создать сплошные области, вам необходимо буферизовать точки в один слой так же, как Географическая информационная система - [этот вопрос] (https://stackoverflow.com/questions/25411251/buffer-geospatial-points-in-r -with-gbuffer) может помочь. – geotheory

ответ

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 вы можете увеличить/уменьшить размер области. См. ?robustbase::covMcd. Btw .: 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

+0

хорошая идея, но что, если у меня есть 2+ области? – groebsgr

+0

Посмотрите на мое редактирование – Rentrop

+0

, что один кажется неплохим, я попробую в следующий раз, на данный момент слишком много вещей, но я, вероятно, дам окончательную реализацию, как я это сделал. Спасибо! – groebsgr

4

Как об использовании panel.smoothScatter из решетки? Он отображает определенное количество точек в регионах с низкой плотностью (см. Аргумент «nrpoints») и везде, где отображаются плотности точек, а не одиночные (и, возможно, перекрывающиеся) точки, что дает более значимые сведения о ваших данных. См. Также ?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

+0

Я знаю об этом «плоттинг-заговоре», это приятно, на мой взгляд, но это не то, что я имею в виду. (извините: D) - тем не менее! – groebsgr

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) 
+0

Я пробовал сейчас около 20 минут. Это могло бы! приводят к результату, который я хочу. Во-первых, я хочу заменить точки под полигоном. Во-вторых, как мне найти связанные области? Может быть, матрица расстояний и только небольшие расстояния для полигона? – groebsgr

Смежные вопросы