Interactive Visualization; Animated Plots
April 21, 2025
plotly::ggplotly()
plotly
is an alternative to ggplot
with a relatively easy to learn syntax for generating many of the same kinds of plots.plotly
is mainly for the interactive figures of visualization.
plotly::ggplotly()
.ggplotly()
interacts with ggplot objects to make those figures interactive.cces <- read_csv(url("https://bcdanl.github.io/data/cces.csv"))
cces <- cces |>
mutate(party = recode(dem, `1` = "Democrat", `0` = "Republican"))
recode()
to create a new variable corresponding to other factor variable.
les
is a score for legislative effectiveness.
ggiraph
ggiraph
is a R package that allows us to create dynamic ggplot.
shiny
applications.tooltip
: tooltips to be displayed when mouse is over elements.data_id
: id
to be associated with elements (necessary for hover and click actions)onclick
: JavaScript to be executed when elements are clicked.The things we need to know to create a ggiraph
interactive graphic:
geom_point
, use geom_point_interactive
.geom_sf
, use geom_sf_interactive
.tooltip
, data_id
and/or onclick
, to create interactive elements.girafe
with the ggplot object so that the graphic is translated as a web interactive graphics.gganimate
mtcars
.gganimate
turn our ggplot visualizations into moving images.
gganimate
takes a ggplot figure and creates many different versions of it by changing a single parameter in the data.transition_states()
transition_states()
is intended to use primarily with categorical variables.
transition_length
and state_length
arguments.seniority
against all_pass
.
seniority
is about how long a member has been in Congress.all_pass
is about how many bills a member passedp <- ggplot() +
geom_jitter(data = filter(cces,
congress==115 & party=="Democrat"),
aes(x = seniority, y = all_pass,
color = party) ) +
geom_jitter(data = filter(cces,
congress==115 & party=="Republican"),
aes(x = seniority, y = all_pass,
color = party) ) +
geom_smooth(data = filter(cces,
congress==115 & party=="Democrat"),
aes(x = seniority, y = all_pass,
color = party) ) +
geom_smooth(data = filter(cces,
congress==115 & party=="Republican"),
aes(x = seniority, y = all_pass,
color = party) ) +
scale_color_manual(values=c("blue","red"))
p
enter_*()
/exit_*()
enter_*()
and exit_*()
allow for controlling the entering and exiting in gganimate
.
*_fade()
will set the alpha value to zero making the elements fade in/out during the transition.shadow_*()
shadow_*()
allows for retaining previous or preview future frames of the animation.
shadow_wake()
shows preceding frames with gradual falloff.
alpha
is for transparency modification of the wake.wrap
should the shadow wrap around, so that the first frame will get shadows from the end of the animation.There are also shadow_mark()
, shadow_null()
, and shadow_trail()
.
p +
geom_text(aes(x = min(gdpPercap),
y = min(lifeExp),
label = as.factor(year)) ,
hjust=-2, vjust = -0.2, alpha = 0.2,
color = "gray", size = 20) +
transition_states(as.factor(year), state_length = 0)
state_length
allows us to control for how long will pause before changing to the new state.view_follow()
view_follow()
function.gapminder |>
filter(country == "United States") |>
ggplot(aes(x = year, y = pop)) +
geom_point() + geom_line() +
geom_text(aes(x = min(year), y = min(pop),
label = as.factor(year)) ,
hjust=-2, vjust = -0.2, alpha = 0.5,
color = "gray", size = 20) +
theme_minimal() +
transition_reveal(year) +
view_follow()
Frames and duration
are the key for a good quality of animation.
We can adjust several key elements of our animations, such as:
width
and height
of the animation to create an animation.fps
): this will make us the animation see fluently.
fps
parameter is recommended to be higher than 12.gif
, you can also create a video too (e.g., mp4
).gdpPercap
for each year
:p <- gapminder_sum |>
ggplot() +
geom_col(aes(x = ranking, y = gdpPercap, fill = country)) +
geom_text(aes(x = ranking, y = gdpPercap, label = round(gdpPercap, 0)),
hjust=-0.1) +
geom_text(aes(x = ranking, y = 0 ,
label = country), hjust=1.1) +
geom_text(aes(x = 15,
y = max(gdpPercap),
label = as.factor(year)),
vjust = 0.2, alpha = 0.5, color = "gray", size = 20) +
coord_flip(clip = "off", expand = FALSE) +
scale_x_reverse() +
theme_minimal() +
theme(
panel.grid = element_blank(),
legend.position = "none",
axis.ticks.y = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank(),
plot.margin = margin(1, 4, 1, 3, "cm")
)
anim <- p +
transition_states(year, state_length = 0, transition_length = 2) +
enter_fade() +
exit_fade() +
ease_aes('quadratic-in-out')
p_anim <- animate(anim,
width = 700, height = 432,
fps = 25, duration = 15,
rewind = FALSE)
p_anim
rewind
: Controls what happens at the end of the sequence.
FALSE
: Jumps back to the first frame and repeats from the beginningTRUE
: After reaching the last frame it’ll play the animation in reverse back to the start