{"id":13654055,"url":"https://github.com/thomasp85/gganimate","last_synced_at":"2025-05-13T15:13:09.417Z","repository":{"id":31984735,"uuid":"50872540","full_name":"thomasp85/gganimate","owner":"thomasp85","description":"A Grammar of Animated Graphics","archived":false,"fork":false,"pushed_at":"2025-03-25T06:56:53.000Z","size":56697,"stargazers_count":1962,"open_issues_count":85,"forks_count":312,"subscribers_count":58,"default_branch":"main","last_synced_at":"2025-04-23T21:44:00.629Z","etag":null,"topics":["animation","data-visualization","ggplot-extension","ggplot2","rstats","transition"],"latest_commit_sha":null,"homepage":"https://gganimate.com","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"dgrtwo/gganimate","license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasp85.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-02-01T21:28:54.000Z","updated_at":"2025-03-25T06:51:20.000Z","dependencies_parsed_at":"2022-07-13T11:20:27.526Z","dependency_job_id":"dbd2aec9-95e3-454d-88ae-659a898e9822","html_url":"https://github.com/thomasp85/gganimate","commit_stats":{"total_commits":416,"total_committers":29,"mean_commits":"14.344827586206897","dds":"0.11538461538461542","last_synced_commit":"facc672534431a140a2e2fa047cfe22eda091903"},"previous_names":["dgrtwo/gganimate"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasp85%2Fgganimate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasp85%2Fgganimate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasp85%2Fgganimate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasp85%2Fgganimate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasp85","download_url":"https://codeload.github.com/thomasp85/gganimate/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253969266,"owners_count":21992264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","data-visualization","ggplot-extension","ggplot2","rstats","transition"],"created_at":"2024-08-02T02:01:22.677Z","updated_at":"2025-05-13T15:13:04.397Z","avatar_url":"https://github.com/thomasp85.png","language":"R","funding_links":[],"categories":["R","ggplot"],"sub_categories":["Animations"],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, echo = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  gganimate = list(\n    nframes = 50\n  )\n)\n```\n\n# gganimate \u003cimg src=\"man/figures/logo.png\" align=\"right\" style=\"padding-left:10px;background-color:white;\" /\u003e\n\n\u003c!-- badges: start --\u003e\n[![R-CMD-check](https://github.com/thomasp85/gganimate/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/thomasp85/gganimate/actions/workflows/R-CMD-check.yaml)\n[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version-ago/gganimate)](https://cran.r-project.org/package=gganimate)\n[![CRAN_Download_Badge](http://cranlogs.r-pkg.org/badges/gganimate)](https://cran.r-project.org/package=gganimate)\n[![Codecov test coverage](https://codecov.io/gh/thomasp85/gganimate/branch/main/graph/badge.svg)](https://app.codecov.io/gh/thomasp85/gganimate?branch=main)\n\u003c!-- badges: end --\u003e\n\n`gganimate` extends the grammar of graphics as implemented by\n[`ggplot2`](https://github.com/tidyverse/ggplot2) to include the description of\nanimation. It does this by providing a range of new grammar classes that can be\nadded to the plot object in order to customise how it should change with time. \n\n- `transition_*()` defines how the data should be spread out and how it relates\n  to itself across time.\n- `view_*()` defines how the positional scales should change along the \n  animation.\n- `shadow_*()` defines how data from other points in time should be presented in\n  the given point in time.\n- `enter_*()`/`exit_*()` defines how new data should appear and how old data \n  should disappear during the course of the animation.\n- `ease_aes()` defines how different aesthetics should be eased during \n  transitions.\n\n## An Example\nAll of the above might seem a bit abstract. Let's try with a contrived example:\n\n```{r, message=FALSE}\nlibrary(ggplot2)\nlibrary(gganimate)\n\nggplot(mtcars, aes(factor(cyl), mpg)) + \n  geom_boxplot() + \n  # Here comes the gganimate code\n  transition_states(\n    gear,\n    transition_length = 2,\n    state_length = 1\n  ) +\n  enter_fade() + \n  exit_shrink() +\n  ease_aes('sine-in-out')\n```\n\nHere we take a simple boxplot of fuel consumption as a function of cylinders and\nlets it transition between the number of gears available in the cars. As this is\na discrete split (`gear` being best described as an ordered factor) we use \n`transition_states` and provides a relative length to use for transition and \nstate view. As not all combinations of data is present there are states missing\na box. We define that when a box appears it should fade into view, whereas at \nshould shrink away when it disappear. Lastly we decide to use a sinusoidal \neasing for all our aesthetics (here, only `y` is changing)\n\n## Installation\n`gganimate` is available on CRAN and can be installed with \n`install.packages('gganimate')`. If you wish to install the development version\nyou can install directly from github using devtools:\n\n```{r, eval=FALSE}\n# install.packages('pak')\npak::pak('thomasp85/gganimate')\n```\n\n## Yet Another Example\nIt is impossible to cover everything possible with `gganimate` in a README, but\nanimations are fun, so let's at least have one more:\n\n```{r}\nlibrary(gapminder)\n\nggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) +\n  geom_point(alpha = 0.7, show.legend = FALSE) +\n  scale_colour_manual(values = country_colors) +\n  scale_size(range = c(2, 12)) +\n  scale_x_log10() +\n  facet_wrap(~continent) +\n  # Here comes the gganimate specific bits\n  labs(title = 'Year: {frame_time}', x = 'GDP per capita', y = 'life expectancy') +\n  transition_time(year) +\n  ease_aes('linear')\n```\n\nIn this example we see the use of `transition_time()` which can be used with \ncontinuous variables such as `year`. With this transition it is not necessary to \nprovide transition and state length as the \"transition variable\" provides this\ndirectly (e.g. it should take twice as long to transition between 1980 and 1990\ncompared to 2000 to 2005). We also see the use of string literal interpolation \nin titles. `gganimate` lets you specify variables to evaluate inside titles and\ndifferent transitions provide different type of information to use.\n\n## Where is my animation?\n`gganimate` mimics the way `ggplot2` renders its output, in that the rendering\nis done automatically when the `gganim` object is printed. Under the hood, the\n`animate()` function is called which renders the frame and passes the frames to\na renderer functions which takes care of combining them to the final animation.\nThe default renderer is `gifski_renderer()` which returns a `gif_image` object\nwhich is a simple wrapper around a path to a gif file. If `animate()` has been\ncalled implicitly as part of `print` the `gif_image` object is available using \nthe `last_animation()` function (analogous to `ggplot2::last_plot()`). In order\nto save the animation to a specific location, you can use the `anim_save()`\nfunction which, like `ggplot2::ggsave`, defaults to taking the last rendered \nanimation and writes it to a file.\n\n## I don't like gifs...\ngif is a fantastic format for animations due to its wide support, but sometimes\nanother format is required. `gganimate` is agnostic to the renderer and while \nthe default is to use [gifski](https://github.com/r-rust/gifski) to combine the\nframes into a gif, it doesn't have to be so. By passing an alternate renderer to\nthe `animate()` function you can control the animation format, and `gganimate` \ncomes with a bunch (and you can write your own). To create video files you can\ne.g. use the `ffmpeg_renderer()`:\n\n```{r, eval=FALSE}\np \u003c- ggplot(airquality, aes(Day, Temp)) + \n  geom_line(size = 2, colour = 'steelblue') + \n  transition_states(Month, 4, 1) + \n  shadow_mark(size = 1, colour = 'grey')\nanimate(p, renderer = ffmpeg_renderer())\n```\n\n*Video output are automatically embedded in RMarkdown documents, but GitHub strips video when rendering READMEs so you can't see it here*\n\nFurther there's support for rendering to sprite sheets if that is your vice.\n\n## Old API\nThis is the second iteration of the gganimate package. The first, developed by\n[David Robinson](https://github.com/dgrtwo) had a very different API, and relied\non specifying animation frame membership inside `aes()` blocks in the `geom_*()`\ncalls. This approach was easy to grasp, but essentially limited in capabilities\nand has thus been abandoned for a more thorough grammar. \n\nCode written for the old API will not work with this `gganimate` version and \nthere will not come a future support for it. If you wish to continue using the \nold API then avoid upgrading `gganimate`. If you've already upgraded and wish to \ndowngrade, the latest version of the old API is available as a \n[GitHub release](https://github.com/thomasp85/gganimate/releases/tag/v0.1.1).\n\nIf you wish to convert your old animations to the new API, the closest you get\nis probably with `transition_manual`, even though it is not completely \nsubstitutable:\n\n```{r, eval=FALSE}\n# Old code\nggplot(mtcars) + \n  geom_boxplot(aes(factor(cyl), mpg, frame = gear))\n\n# New code\nggplot(mtcars) + \n  geom_boxplot(aes(factor(cyl), mpg)) + \n  transition_manual(gear)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasp85%2Fgganimate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasp85%2Fgganimate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasp85%2Fgganimate/lists"}