Gözlemle bir histogram gözlemi oluşturmak için gganimate kullanılsın mı? Daha büyük veri kümeleri için çalışması gerekir (~ n = 5000)


11

Normal bir dağılımdan noktaları örneklemek ve daha sonra gganimateson kare tam dotplot gösterene kadar paketi kullanarak tek tek bir nokta grafiği oluşturmak istiyorum.

Daha büyük veri kümeleri için çalışan bir çözüm ~ 5.000 - 20.000 nokta gereklidir.

İşte şimdiye kadar sahip olduğum kod:

library(gganimate)
library(tidyverse)

# Generate 100 normal data points, along an index for each sample 
samples <- rnorm(100)
index <- seq(1:length(samples))

# Put data into a data frame
df <- tibble(value=samples, index=index)

Df şöyle görünür:

> head(df)
# A tibble: 6 x 2
    value index
    <dbl> <int>
1  0.0818     1
2 -0.311      2
3 -0.966      3
4 -0.615      4
5  0.388      5
6 -1.66       6

Statik grafik doğru nokta grafiğini gösterir:

# Create static version
plot <- ggplot(data=df, mapping=aes(x=value))+
          geom_dotplot()

Ancak, gganimatesürüm bunu yapmaz (aşağıya bakınız). Noktaları yalnızca x eksenine yerleştirir ve istiflemez.

plot+
  transition_reveal(along=index)

Statik çizim

resim açıklamasını buraya girin

Buna benzer bir şey ideal olurdu: Kredi: https://gist.github.com/thomasp85/88d6e7883883315314f341d2207122a1 resim açıklamasını buraya girin


Heya. Daha iyi aranabilirlik için farklı bir başlık önerebilir miyim? Bu animasyonlu histogramı gerçekten sevmeye başladım ve bunun harika bir görselleştirme olduğunu düşünüyorum ... Sth "Animasyonlu nokta histogramı, gözlemle inşa edilmiş gözlem" gibi daha uygun olabilir mi?
Tjebo

Yanıtlar:


10

Başka bir seçenek de noktaları başka bir geom ile çizmektir. önce verilerinizde (ve binning'de) bazı sayımlar yapmanız gerekir, ancak verilerinizin daha uzun süre yapılmasını gerektirmez.

Örneğin, geom_point , ancak zorluk noktalarınızın boyutlarını doğru bir şekilde elde etmek olacaktır, böylece dokunurlar / dokunmazlar. Bu, görüntü alanına / dosya boyutuna bağlıdır.

Ama sadece ggforce::geom_ellipsenoktalarınızı çizmek için de kullanabilirsiniz :)

geom_point (görünüm boyutu ile deneme yanılma)

library(tidyverse)
library(gganimate)

set.seed(42)
samples <- rnorm(100)
index <- seq(1:length(samples))
df <- tibble(value = samples, index = index)

bin_width <- 0.25

count_data <- # some minor data transformation
  df %>%
  mutate(x = plyr::round_any(value, bin_width)) %>%
  group_by(x) %>%
  mutate(y = seq_along(x))

plot <-
  ggplot(count_data, aes(group = index, x, y)) + # group by index is important
  geom_point(size = 5)

p_anim <- 
  plot +
  transition_reveal(index)

animate(p_anim, width = 550, height = 230, res = 96)

geom_ellipse (Nokta büyüklüğünün tam kontrolü)

library(ggforce)
plot2 <- 
  ggplot(count_data) +
  geom_ellipse(aes(group = index, x0 = x, y0 = y, a = bin_width/2, b = 0.5, angle = 0), fill = 'black') +
  coord_equal(bin_width) # to make the dots look nice and round

p_anim2 <- 
  plot2 +
  transition_reveal(index) 

animate(p_anim2) 

GüncellemeThomas'ın şaşırtıcı örneğine verdiğiniz bağlantıda , benzer bir yaklaşım kullandığını görebilirsiniz - hem dikey hem de yatay yarıçap için daha iyi kontrol nedeniyle seçtiğim geom_ellipse yerine geom_circle kullanıyor.

"Düşen damlalar" etkisini elde etmek için ihtiyacınız olacak transition_statesve uzun bir süre ve saniyede birçok kare.

p_anim2 <- 
  plot2 +
  transition_states(states = index, transition_length = 100, state_length = 1) +
  shadow_mark() +
  enter_fly(y_loc = 12) 

animate(p_anim2, fps = 40, duration = 20) 

2020-04-29 tarihinde reprex paketi tarafından oluşturuldu (v0.3.0)

biraz ilham kaynağı: ggplot dotplot: geom_dotplot'un doğru kullanımı nedir?


Y değerine göre satırlar halinde değil, tek tek gelmek için puan arıyorum.
fazla

2
@max güncellemeye bakın - y'yi index ile değiştirin.
Tjebo

3

Bunu dene. Temel fikir gruba obs çerçevelere, yani indekse bölünür ve sonra örnekleri çerçevelere biriktirir, yani çerçeve 1'de sadece ilk obs gösterilir, çerçeve 2 obs 1 ve 2, ..... Belki de orada bunu başarmanın daha zarif bir yoludur, ancak işe yarar:

library(ggplot2)
library(gganimate)
library(dplyr)
library(purrr)

set.seed(42)

# example data
samples <- rnorm(100)
index <- seq(1:length(samples))

# Put data into a data frame
df <- tibble(value=samples, index=index)

# inflated df. Group obs together into frames
df_ani <- df %>% 
  split(.$index) %>% 
  accumulate(~ bind_rows(.x, .y)) %>% 
  bind_rows(.id = "frame") %>% 
  mutate(frame = as.integer(frame))
head(df_ani)
#> # A tibble: 6 x 3
#>   frame  value index
#>   <int>  <dbl> <int>
#> 1     1  1.37      1
#> 2     2  1.37      1
#> 3     2 -0.565     2
#> 4     3  1.37      1
#> 5     3 -0.565     2
#> 6     3  0.363     3

p_gg <- ggplot(data=df, mapping=aes(x=value))+
  geom_dotplot()
p_gg
#> `stat_bindot()` using `bins = 30`. Pick better value with `binwidth`.

p_anim <- ggplot(data=df_ani, mapping=aes(x=value))+
  geom_dotplot()

anim <- p_anim + 
  transition_manual(frame) +
  ease_aes("linear") +
  enter_fade() +
  exit_fade()
anim
#> `stat_bindot()` using `bins = 30`. Pick better value with `binwidth`.

2020-04-27 tarihinde reprex paketi tarafından oluşturuldu (v0.3.0)


bu işe yarar, ancak tablo çok sayıda yinelenen veri satırı içerdiğinden, daha büyük veri kümeleri için hızla kullanılamaz hale gelir.
maksimum

örneğin, 5000 noktayı çizmek için, veri çerçevesinin 12 milyon satırı vardır :(
maks.

Geç cevap verdiğim için üzgünüm. Şu anda biraz meşgul. Evet. Senin değinmek istediğin noktayı anlıyorum. Bu tür bir soruna daha iyi ve daha ileriye dönük bir çözüm olması gerektiğine eminim. Ancak, hala gganimate için bir acemi değilim ve şimdiye kadar tüm olanaklarını ve özelliklerini kontrol etmek için zamanım yoktu. Korkarım şu an için daha iyi bir çözüm bulamıyorum.
stefan

3

Buradaki anahtarın, bu animasyonu manuel olarak nasıl oluşturacağınızı hayal etmek olduğunu düşünüyorum, yani ortaya çıkan nokta grafiğine her seferinde bir gözlem noktası ekleyeceksiniz. Bunu göz önünde bulundurarak, burada kullandığım yaklaşım ggplot, komplo katmanları = gözlem sayısı, ardından adım adım katmandan oluşan bir nesne yaratmaktı transition_layer.

# create the ggplot object
df <- data.frame(id=1:100, y=rnorm(100))

p <- ggplot(df, aes(y))

for (i in df$id) {
  p <- p + geom_dotplot(data=df[1:i,])
}

# animation
anim <- p + transition_layers(keep_layers = FALSE) +
    labs(title='Number of dots: {frame}')
animate(anim, end_pause = 20, nframes=120, fps=20)

resim açıklamasını buraya girin

keep_layers=FALSEFazla çizmeyi önlemek için ayarladığımı unutmayın . İlk ggplotnesneyi çizerseniz, ilk gözlem 100 kez, ikinci 99 kez çizildiğinden, ne demek istediğimi görürsünüz.

Daha büyük veri kümeleri için ölçeklendirme yapmaya ne dersiniz?

Kare sayısı = gözlem sayısı olduğundan, ölçeklenebilirlik için ayar yapmanız gerekir. Burada, # kareleri sabit tutmanız yeterlidir, yani kodun kareleri seq()işlev aracılığıyla yaptığım parçalara ayırmasına izin vermeniz gerekir length.out=100. Yeni örnekte veri kümesinin de bulunduğunu unutmayın n=5000. Nokta grafiğini çerçevede tutmak için noktaların boyutlarını gerçekten küçültmeniz gerekir. Ben muhtemelen burada noktaları biraz fazla küçük yaptım, ama siz fikir. Şimdi # kare = gözlem grubu sayısı.

df <- data.frame(id=1:5000, y=rnorm(5000))

p <- ggplot(df, aes(y))

for (i in seq(0,length(df$id), length.out=100)) {
  p <- p + geom_dotplot(data=df[1:i,], dotsize=0.08)
}

anim <- p + transition_layers(keep_layers=FALSE) +
  labs(title='Frame: {frame}')

animate(anim, end_pause=20, nframes=120, fps=20)

resim açıklamasını buraya girin


Bu, küçük veri kümeleri için iyi çalışır, ancak orta derecede büyük verilere bile iyi ölçeklenmez (n = 5000).
maksimum

İşte hata n = 5000 için raporlar: Hata: C yığını kullanımı 7969904 sınıra çok yakın
max

Evet, burada örnekte çerçeve = gözlem sayısı vardır. Sana ölçekleme sonra 100'de # çerçeveleri sabit tutup ölçeklenebilirlik, için cevap kaydetmiştiniz o çerçeveler böylece = gözlem sayısı gruplarına
chemdork123
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.