Çok fazla noktaya sahip dağılım grafiği


126

N = 700K olan iki değişkeni çizmeye çalışıyorum. Sorun, çok fazla örtüşme olması, dolayısıyla olay örgüsünün çoğunlukla siyah bir blok haline gelmesi. Grafiğin karanlığının bir bölgedeki nokta sayısının bir fonksiyonu olduğu gri tonlamalı bir "bulut" sahibi olmanın herhangi bir yolu var mı? Başka bir deyişle, tek tek noktaları göstermek yerine, arsanın bir "bulut" olmasını istiyorum, bir bölgedeki nokta sayısı ne kadar fazlaysa, o bölge o kadar karanlık.


4
Bir ısı

Yanıtlar:


145

Bununla başa çıkmanın bir yolu, her noktayı biraz şeffaf yapan alfa harmanlamadır. Böylece bölgeler, üzerlerinde daha fazla nokta işaretlenmiş olan daha koyu görünür.

Bunu yapmak kolaydır ggplot2:

df <- data.frame(x = rnorm(5000),y=rnorm(5000))
ggplot(df,aes(x=x,y=y)) + geom_point(alpha = 0.3)

görüntü açıklamasını buraya girin

Bununla başa çıkmanın bir başka uygun yolu (ve muhtemelen sahip olduğunuz nokta sayısı için daha uygun olan) altıgen gruplamadır:

ggplot(df,aes(x=x,y=y)) + stat_binhex()

görüntü açıklamasını buraya girin

Ayrıca, geleneksel ısı haritanıza daha çok benzeyen normal eski dikdörtgen gruplama (resim atlanmıştır) vardır:

ggplot(df,aes(x=x,y=y)) + geom_bin2d()

1
Renkleri nasıl değiştirebilirim? Şimdi maviden siyaha ölçek alıyorum, oysa reg, yeşil mavi skala almak istiyorum.
user1007742

@ user1007742 scale_fill_gradient()Kendi düşük ve yüksek renklerinizi kullanın ve belirtin veya scale_fill_brewer()sıralı paletlerden birini kullanın ve seçin.
joran

@joran teşekkürler, şimdi çalışıyor. Noktaların türünü / şeklini değiştirmeye ne dersiniz? Ya altıgen ya da kare alırım. Ben sadece basit noktalar istiyorum. Geom_point () kullandığımda hata veriyor.
user1007742

1
@ user1007742 Bir sebepten dolayı buna "altıgen gruplama" deniyor! ;) "Noktalar" çizmiyor, tüm bölgeyi altıgen (veya dikdörtgen) kutulara bölüyor ve ardından kutuları, o bölmede kaç nokta olduğuna bağlı olarak basitçe renklendiriyor. Yani kısa cevap "yapamazsın". Farklı şekiller istiyorsanız, geom_point()her noktayı ayrı ayrı kullanmanız ve çizmeniz gerekir .
joran

Ya 3B verilerim varsa?
skan

60

ggsubplotPakete de bir göz atabilirsiniz . Bu paket, 2011'de Hadley Wickham tarafından sunulan özellikleri uygular ( http://blog.revolutionanalytics.com/2011/10/ggplot2-for-big-data.html ).

(Aşağıda, örnekleme amacıyla "puan" katmanını ekledim.)

library(ggplot2)
library(ggsubplot)

# Make up some data
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=5000),
                  xvar = c(rep(1:20,250) + rnorm(5000,sd=5),rep(16:35,250) + rnorm(5000,sd=5)),
                  yvar = c(rep(1:20,250) + rnorm(5000,sd=5),rep(16:35,250) + rnorm(5000,sd=5)))


# Scatterplot with subplots (simple)
ggplot(dat, aes(x=xvar, y=yvar)) +
  geom_point(shape=1) +
  geom_subplot2d(aes(xvar, yvar,
                     subplot = geom_bar(aes(rep("dummy", length(xvar)), ..count..))), bins = c(15,15), ref = NULL, width = rel(0.8), ply.aes = FALSE)

görüntü açıklamasını buraya girin

Bununla birlikte, kontrol etmeniz gereken üçüncü bir değişkeniniz varsa bu özellikler sarsılır.

# Scatterplot with subplots (including a third variable) 

ggplot(dat, aes(x=xvar, y=yvar)) +
  geom_point(shape=1, aes(color = factor(cond))) +
  geom_subplot2d(aes(xvar, yvar,
                     subplot = geom_bar(aes(cond, ..count.., fill = cond))),
                 bins = c(15,15), ref = NULL, width = rel(0.8), ply.aes = FALSE)  

görüntü açıklamasını buraya girin

Veya başka bir yaklaşım kullanmak olacaktır smoothScatter():

smoothScatter(dat[2:3])

görüntü açıklamasını buraya girin


3
bu ikinci arsa harika!
Ricardo Saporta

Ya 3B verilerim varsa?
skan

2
@ skan: Bunun için yeni bir soru açabilirsiniz.
majom

maalesef ggsubplot paketi artık bakım yapılmıyor ve cran repodan kaldırılıyor ... yukarıdaki ilk ikisi gibi grafikler oluşturmak için kullanılabilecek alternatif bir paket biliyor musunuz?
dieHellste

R & ggplot2'nin eski bir sürümünü kullanıyorsanız, onu çalıştırabilmelisiniz
majom

59

Aşağıdaki birkaç iyi seçeneğe genel bakış ggplot2:

library(ggplot2)
x <- rnorm(n = 10000)
y <- rnorm(n = 10000, sd=2) + x
df <- data.frame(x, y)

Seçenek A: şeffaf noktalar

o1 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.05)

Seçenek B: yoğunluk konturları ekleyin

o2 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.05) +
  geom_density_2d()

Seçenek C: Dolu yoğunluk konturları ekleyin

o3 <- ggplot(df, aes(x, y)) +
  stat_density_2d(aes(fill = stat(level)), geom = 'polygon') +
  scale_fill_viridis_c(name = "density") +
  geom_point(shape = '.')

Seçenek D: yoğunluk ısı haritası

o4 <- ggplot(df, aes(x, y)) +
  stat_density_2d(aes(fill = stat(density)), geom = 'raster', contour = FALSE) +       
  scale_fill_viridis_c() +
  coord_cartesian(expand = FALSE) +
  geom_point(shape = '.', col = 'white')

Seçenek E: heksbinler

o5 <- ggplot(df, aes(x, y)) +
  geom_hex() +
  scale_fill_viridis_c() +
  geom_point(shape = '.', col = 'white')

Seçenek F: kilimler

o6 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.1) +
  geom_rug(alpha = 0.01)

Tek bir şekilde birleştirin:

cowplot::plot_grid(
  o1, o2, o3, o4, o5, o6,
  ncol = 2, labels = 'AUTO', align = 'v', axis = 'lr'
)

görüntü açıklamasını buraya girin


1
Bu, biraz daha fazla oyu hak ettiğini düşündüğüm çok güzel bir cevap.
Lalochezia

Bana bir hata veriyor scale_fill_viridis_c () 'de hata: "scale_fill_viridis_c" işlevi bulunamadı
JustGettinStarted

ggplot2 güncellendi, ggplot2 yeniden yüklendi ve ggplot2 yeniden yüklendi. Hatayı düzeltmedi. Ayrı olarak kurulan 'viridis' paketi ve bu 'scale_fill_viridis' işlevini kullanmama izin veriyor, ancak aynı hatayı veren 'scale_fill_viridis_c' işlevini kullanmama izin veriyor
JustGettinStarted

oh sana inanıyorum Orada sorun yok. Sadece hatanın altına inmeye çalışıyorum.
JustGettinStarted

51

Alfa harmanlamanın temel grafiklerle de yapılması kolaydır.

df <- data.frame(x = rnorm(5000),y=rnorm(5000))
with(df, plot(x, y, col="#00000033"))

Bundan sonraki ilk altı sayı #RGB onaltılık renktir ve son ikisi opaklıktır, yine onaltılıktır, yani 33 ~ 3 / 16ncı opaktır.

görüntü açıklamasını buraya girin


20
Biraz bağlam eklemek için, "# 000000" siyah renktir ve rengin sonuna eklenen "33" opaklık derecesidir - burada% 33.
Charlie

Eklenen açıklama için teşekkürler.
Aaron Stack Overflow'dan

Mantıklı gelir. Teşekkürler, hem Aaron hem de Charlie.
user702432

12
Küçük not; sayılar onaltılıktır, bu nedenle 33 aslında 3 / 16'ncı opaktır.
Aaron Stack Overflow'dan

45

Ayrıca yoğunluk kontur çizgilerini ( ggplot2) de kullanabilirsiniz :

df <- data.frame(x = rnorm(15000),y=rnorm(15000))
ggplot(df,aes(x=x,y=y)) + geom_point() + geom_density2d()

görüntü açıklamasını buraya girin

Veya yoğunluk konturlarını alfa harmanlama ile birleştirin:

ggplot(df,aes(x=x,y=y)) + 
    geom_point(colour="blue", alpha=0.2) + 
    geom_density2d(colour="black")

görüntü açıklamasını buraya girin


29

hexbinPaketi faydalı bulabilirsiniz . Yardım sayfasından hexbinplot:

library(hexbin)
mixdata <- data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)),
                      y = c(rnorm(5000),rnorm(5000,2,3)),
                      a = gl(2, 5000))
hexbinplot(y ~ x | a, mixdata)

hexbinplot


+1 hexbin benim tercih ettiğim çözüm - çok sayıda nokta alabilir ve ardından güvenli bir şekilde bir grafik oluşturabilir. Diğerlerinin bir olay örgüsü oluşturmaya çalışmayacağından emin değilim, ancak işleri daha önce farklı şekilde gölgelendirin.
Iterator

3D veriler için hexbin gibi bir şey var mı?
skan

8

geom_pointdenistydan ggpointdensitypaketin aynı anda yoğunluğa ve bireysel veri noktaları görselleştirmek sağlar (son zamanlarda Lukas Kremer ve Simon Anders (2019) tarafından geliştirilen):

library(ggplot2)
# install.packages("ggpointdensity")
library(ggpointdensity)

df <- data.frame(x = rnorm(5000), y = rnorm(5000))
ggplot(df, aes(x=x, y=y)) + geom_pointdensity() + scale_color_viridis_c()


2

Bu tür verileri çizmek için en sevdiğim yöntem, bu soruda açıklanan yöntemdir - bir dağılım yoğunluğu grafiği . Buradaki fikir, bir dağılım grafiği yapmak, ancak noktaları yoğunluklarına göre renklendirmektir (kabaca konuşursak, o alandaki örtüşme miktarı).

Aynı anda:

  • aykırı değerlerin konumunu açıkça gösterir ve
  • arsanın yoğun alanındaki herhangi bir yapıyı ortaya çıkarır.

Bağlantılı soruya verilen en üst yanıtın sonucu:

dağılım yoğunluğu grafiği


1
Bu benim de en sevdiğim yol. Bunu nasıl başaracağıma dair cevabıma bakın R.
jan-glx
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.