gganimate를 사용하여 관찰로 히스토그램 관찰을 작성 하시겠습니까? 더 큰 데이터 세트에 대해 작동해야 함 (~ n = 5000)


10

정규 분포에서 점을 샘플링 한 다음 gganimate최종 프레임에 전체 점표가 표시 될 때까지 패키지를 사용하여 점표를 하나씩 작성하고 싶습니다 .

더 큰 데이터 세트에 ~ 5,000-20,000 포인트를 지원하는 솔루션이 필수적입니다.

지금까지 내가 가지고있는 코드는 다음과 같습니다.

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는 다음과 같습니다.

> 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

정적 플롯은 올바른 도트 플롯을 보여줍니다.

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

그러나 gganimate버전은 그렇지 않습니다 (아래 참조). x 축에만 점을 배치하고 쌓지 않습니다.

plot+
  transition_reveal(along=index)

정적 플롯

여기에 이미지 설명을 입력하십시오

이와 비슷한 것이 이상적입니다 : 신용 : https://gist.github.com/thomasp85/88d6e7883883315314f341d2207122a1 여기에 이미지 설명을 입력하십시오


헤야 더 나은 검색 가능성을 위해 다른 제목을 제안해도됩니까? 나는이 애니메이션 히스토그램을 정말로 좋아하기 시작했고, 그것이 훌륭한 시각화라고 생각합니다. "애니메이션 도트 히스토그램, 관찰에 의한 관찰 결과"와 같은 Sth가 더 관련이 있을까요?
Tjebo

답변:


9

다른 옵션은 다른 형상으로 점을 그리는 것입니다. 먼저 데이터를 계산하고 비닝해야하지만 데이터를 더 길게 만들 필요는 없습니다.

예를 들어,을 사용할 수 geom_point있지만 문제는 포인트의 크기를 올바르게 파악하여 터치 / 만지지 않는 것입니다. 이것은 뷰포트 / 파일 크기에 따라 다릅니다.

그러나 ggforce::geom_ellipse점을 그리는 데 사용할 수도 있습니다.)

geom_point (뷰포트 크기의 시험 및 오류)

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 (점 크기 전체 제어)

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) 

토마스의 놀라운 예를 제공하는 링크에서 업데이트 하면 비슷한 접근 방식을 사용한다는 것을 알 수 있습니다-그는 geom_ellipse 대신 geom_circle을 사용합니다. 이는 수직 및 수평 반경에 대한 더 나은 제어로 인해 선택했습니다.

"떨어지는 방울"효과를 얻으려면 transition_states초당 긴 시간과 많은 프레임 이 필요합니다 .

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) 

reprex 패키지 (v0.3.0)로 2020-04-29에 작성

ggplot dotplot : geom_dotplot의 올바른 사용법은 무엇입니까?


Y 값에 따라 행이 아닌 하나씩 하나씩 포인트를 찾고 있습니다.
최대

2
@max는 update를 참조하십시오-y를 index로 바꾸십시오.
Tjebo

3

이 시도. 기본 아이디어는 obs를 프레임으로 그룹화하는 것입니다. 즉, 인덱스로 분할 한 다음 샘플을 프레임에 누적합니다. 즉, 프레임 1에서 첫 번째 obs 만 프레임 2 obs 1 및 2에 표시됩니다. 이것을 달성하는보다 우아한 방법이지만 작동합니다.

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`.

reprex 패키지 (v0.3.0)로 2020-04-27에 작성


이 기능은 작동하지만 테이블에 중복 된 데이터 행이 많기 때문에 더 큰 데이터 세트에는 빠르게 사용할 수 없습니다.
최대

예를 들어, 5000 포인트를 표시하기 위해 데이터 프레임에는 1200 만 개의 행이 있습니다.
최대

늦은 답변 죄송합니다. 지금 조금 바빠요. 예. 너의 의도를 알 겠어. 나는 이런 종류의 문제에 대해 더 좋고 더 확실한 해결책이 있어야한다고 확신한다. 그러나 나는 여전히 gganimate의 초보자이며 지금까지는 모든 가능성과 기능을 확인할 시간이 없었습니다. 따라서 현재로서는 더 나은 솔루션을 찾을 수 없습니다.
스테판

3

여기서 중요한 점은이 애니메이션을 수동으로 생성하는 방법을 상상하는 것입니다. 즉, 결과 도트 플롯에 한 번에 하나의 관측치를 도트를 추가한다고합니다. 이것을 염두에두고, 여기에 사용한 접근법 ggplot은 플롯 레이어 = 관측치 수로 구성된 객체를 만든 다음 비아를 통해 단계별로 수행 하는 것이 었습니다 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)

여기에 이미지 설명을 입력하십시오

keep_layers=FALSE오버 플로팅을 피하기 위해 설정 했습니다. 초기 ggplot객체를 플로팅하면 첫 번째 관측치가 100 번, 두 번째 99 번 등이 그려지기 때문에 의미하는 것을 볼 수 있습니다.

더 큰 데이터 세트에 대한 확장은 어떻습니까?

프레임 수 = 관측치 수이므로 확장 성을 조정해야합니다. 여기서는 # 프레임을 일정하게 유지하십시오. 즉, 코드를 통해 프레임을 세그먼트로 그룹화해야합니다 . 이 seq()함수 를 통해 수행하고 length.out=100있습니다. 새 예제에서도 데이터 세트에 포함 n=5000됩니다. 도트 플롯을 프레임에 유지하려면 도트 크기를 정말 작게 만들어야합니다. 아마도 여기에 점을 너무 작게 만들었을 것입니다. 이제 # 프레임 = 관측 그룹 수입니다.

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)

여기에 이미지 설명을 입력하십시오


작은 데이터 집합에는 효과적이지만 중간 정도의 큰 데이터에도 잘 맞지 않습니다 (n = 5000).
최대

오류 : 다음은 오류가 N = 5000에 대한 보고서입니다 C 스택 사용량 7,969,904 너무 가까이 제한하는 것입니다
최대

예, 여기 예제에는 프레임 = 관측치 수가 있습니다. 확장성에 대한 답변을 편집했습니다. 여기서 # 프레임을 100으로 일정하게 유지 한 다음 프레임 = 관측 그룹 수
chemdork123
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.