I am trying to make a gif(for each frame I want to plot the variable in the y axis, and the value in x axis), but bit struggled to fix the plot position since it will move once the length of the variable in y axis changes.
Here is one reproducible example:
packs <- c("data.table","tidyverse","scales","magick")
lapply(packs,require,character.only=T)
data <- data.table(variable=c(letters[1:6],"agdjfhgbbkf"),
                   values=c(1:7))
data$variable_levels <- fct_reorder(data$variable, data$values)
generate_frame <- function(data, i) {
  
  # create the plot
  p <- ggplot(data[1:i,], aes(x = values, y = variable_levels)) +
    geom_col(fill = "#4285F4", position = position_dodge()) +
    scale_x_continuous(limits = c(0, max(data$values)),labels = scales::comma) +
    scale_y_discrete(limits = rev(levels(data$variable_levels)),
                     labels = function(x) {
                       wrap_format(10)(ifelse(x %in% data$variable_levels[1:i], x, ""))
                     }) +
    # set y-axis limits
    theme_bw() +
    theme(axis.text = element_text(family = "mono"),
          panel.grid.major.y = element_blank(),
          axis.line.y = element_blank(),
          axis.text.y = element_text(hjust = 1, size = 10),
          axis.ticks.y = element_blank(),
          axis.title.y = element_blank(),
          plot.margin = margin(t = 1, r = 1, b = 1, l = 5, unit = "cm"))+
    labs(x="Value",y="",title="")
  
  
  # save the plot as a png file
  ggsave(paste0("frame_", i, ".png"), p, width = 800, height = 400, dpi = 150,units='px')
}
# generate all the frames
for (i in 1:nrow(data)) {
  generate_frame(data, i)
}
# create an empty image list
image_list <- image_blank(width = 800, height = 400)
# read in each frame and add it to the image list
for (i in 1:nrow(data)) {
  frame_file <- paste0("frame_", i, ".png")
  frame_image <- image_read(frame_file)
  image_list <- c(image_list, frame_image)
}
# combine all frames into a GIF and save it
image_write(image_list, "animation.gif", format = "gif")
I have tried to use expand() in scale_y_discrete() , but it does not work.
I would appreciate it if someone can show me how to fix the plot position and define the interval between each frame.
PS: also tried to use gganimate, but not sure how to make the occurence of the variable in y axis dynamically
 library(gganimate)
 library(ggplot2)
ggplot(data, aes(x = variable, y = values)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_x_continuous(limits = c(0, max(data$values)),labels = scales::comma) +
  scale_y_discrete(limits = rev(levels(data$variable_levels)),
                   labels = function(x) {
                     wrap_format(20)(ifelse(x %in% data$variable_levels, x, ""))
                   }
                   ) +
  # set y-axis limits
  theme_bw() +
  theme(axis.text = element_text(family = "mono"),
        panel.grid.major.y = element_blank(),
        axis.line.y = element_blank(),
        axis.text.y = element_text(hjust = 1, size = 10),
        axis.ticks.y = element_blank(),
        axis.title.y = element_blank())+
  labs(x="Value",y="")+
  transition_states(variable_levels, wrap = F)  +
  shadow_mark()
