There are so many beautiful “π” arts everywhere, and I wanted to practice ggplot2 by mimicing those arts further more. Another pi art caught my eye is random walk of pi digits. Here’s one of examples in WIRED magazine.
For random walk to work, I’ve assigned direction to “walk” depending on digits 0-9.
I’ve prepared data frame as below, so I can use ggplot2 to plot
## pi_df contains first 100K digits , each digit is stored in one row.
df_walk % mutate(pos = row_number()-1, ## assign position
dig= as.numeric(dig)) %__%
select(pos, dig) %__%
mutate(angle_rad = 2*pi/10*dig, ## using current digit determine direction to move
angle_deg = circular::deg(angle_rad), ## I just like to see number in degree...
move_x = cos(angle_rad), ## how much to move in x direction
move_y = sin(angle_rad), ## how much to move in y direction
last_x = replace_na(lag(move_x),0), ## position of last x, set origin as 0
last_y = replace_na(lag(move_y),0), ## position of last y, set origin as 0
cumsum_x = cumsum(move_x), ## walkig == adding up all steps in x
cumsum_y = cumsum(move_y), ## walking == adding up all steps in y
cumsum_x_lag = cumsum(last_x),
cumsum_y_lag = cumsum(last_y)) df_walk %__% head(n=5) %__% knitr::kable()
pos
dig
angle_rad
angle_deg
move_x
move_y
last_x
last_y
cumsum_x
cumsum_y
cumsum_x_lag
cumsum_y_lag
0
3
1.8849556
108
-0.309017
0.9510565
0.000000
0.0000000
-0.309017
0.9510565
0.000000
0.0000000
1
1
0.6283185
36
0.809017
0.5877853
-0.309017
0.9510565
0.500000
1.5388418
-0.309017
0.9510565
2
4
2.5132741
144
-0.809017
0.5877853
0.809017
0.5877853
-0.309017
2.1266270
0.500000
1.5388418
3
1
0.6283185
36
0.809017
0.5877853
-0.809017
0.5877853
0.500000
2.7144123
-0.309017
2.1266270
4
5
3.1415927
180
-1.000000
0.0000000
0.809017
0.5877853
-0.500000
2.7144123
0.500000
2.7144123
Now to visualize the random walk, I’ve used below script to visualize first 1000, first 10000 and first 100000 digits of pi.
n_steps % filter(pos __ n_steps) %__%
ggplot(aes(x=cumsum_x, y=cumsum_y, color=pos)) + geom_segment(size=0.5, aes(xend=cumsum_x_lag, yend=cumsum_y_lag)) +
geom_point(size=0.8) + theme_void(base_family=&quot;Roboto Condensed&quot;) +
theme(panel.background=element_rect(fill=&quot;#000000&quot;)) +
scale_color_viridis_c(option=&quot;plasma&quot;, guide=&quot;none&quot;) +
labs(caption=paste(&quot;First&quot;,n_steps,&quot;digits of Pi&quot;)) +
geom_hline(yintercept=0, color=&quot;#ffffff30&quot;, linetype=3) +
geom_vline(xintercept=0, color=&quot;#ffffff30&quot;, linetype=3)
#ggsave(str_c(&quot;output/random_walk_pi_&quot;,n_steps,&quot;.png&quot;), width=11, height=7)
n_steps % filter(pos __ n_steps) %__%
ggplot(aes(x=cumsum_x, y=cumsum_y, color=pos)) + geom_segment(size=0.1, aes(xend=cumsum_x_lag, yend=cumsum_y_lag)) +
geom_point(size=0.01) + theme_void(base_family=&quot;Roboto Condensed&quot;) +
theme(panel.background=element_rect(fill=&quot;#000000&quot;)) +
scale_color_viridis_c(option=&quot;plasma&quot;, guide=&quot;none&quot;) +
labs(caption=paste(&quot;First&quot;,n_steps,&quot;digits of Pi&quot;)) +
geom_hline(yintercept=0, color=&quot;#ffffff30&quot;, linetype=3) +
geom_vline(xintercept=0, color=&quot;#ffffff30&quot;, linetype=3)
n_steps % filter(pos __ n_steps) %__%
ggplot(aes(x=cumsum_x, y=cumsum_y, color=pos)) + geom_segment(size=0.1, aes(xend=cumsum_x_lag, yend=cumsum_y_lag)) +
geom_point(size=0.005) + theme_void(base_family=&quot;Roboto Condensed&quot;) +
theme(panel.background=element_rect(fill=&quot;#000000&quot;)) +
scale_color_viridis_c(option=&quot;plasma&quot;, guide=&quot;none&quot;) +
labs(caption=paste(&quot;First 100000 digits of Pi&quot;)) +
geom_hline(yintercept=0, color=&quot;#ffffff30&quot;, linetype=3) +
geom_vline(xintercept=0, color=&quot;#ffffff30&quot;, linetype=3)