[r] gganimate를 사용하여 관찰로 히스토그램 관찰을 작성 하시겠습니까? 더 큰 데이터 세트에 대해 작동해야 함 (~ n = 5000)
정규 분포에서 점을 샘플링 한 다음 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
답변
다른 옵션은 다른 형상으로 점을 그리는 것입니다. 먼저 데이터를 계산하고 비닝해야하지만 데이터를 더 길게 만들 필요는 없습니다.
예를 들어,을 사용할 수 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에 작성
답변
이 시도. 기본 아이디어는 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에 작성
답변
여기서 중요한 점은이 애니메이션을 수동으로 생성하는 방법을 상상하는 것입니다. 즉, 결과 도트 플롯에 한 번에 하나의 관측치를 도트를 추가한다고합니다. 이것을 염두에두고, 여기에 사용한 접근법 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)