{"id":13689241,"url":"https://github.com/jwkvam/celluloid","last_synced_at":"2025-05-15T06:06:29.224Z","repository":{"id":56793052,"uuid":"157944871","full_name":"jwkvam/celluloid","owner":"jwkvam","description":":movie_camera: Matplotlib animations made easy","archived":false,"fork":false,"pushed_at":"2024-02-16T17:12:46.000Z","size":36,"stargazers_count":1132,"open_issues_count":20,"forks_count":43,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-14T12:10:34.610Z","etag":null,"topics":["animation","matplotlib","matplotlib-animation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jwkvam.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2018-11-17T02:53:47.000Z","updated_at":"2025-04-08T12:56:56.000Z","dependencies_parsed_at":"2024-06-18T14:07:53.953Z","dependency_job_id":null,"html_url":"https://github.com/jwkvam/celluloid","commit_stats":{"total_commits":37,"total_committers":1,"mean_commits":37.0,"dds":0.0,"last_synced_commit":"037ed04de428fed6f82203446fe43d5168db361b"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwkvam%2Fcelluloid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwkvam%2Fcelluloid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwkvam%2Fcelluloid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwkvam%2Fcelluloid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jwkvam","download_url":"https://codeload.github.com/jwkvam/celluloid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254283339,"owners_count":22045140,"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","matplotlib","matplotlib-animation"],"created_at":"2024-08-02T15:01:39.687Z","updated_at":"2025-05-15T06:06:29.206Z","avatar_url":"https://github.com/jwkvam.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# celluloid\n\n[![Build Status](https://travis-ci.com/jwkvam/celluloid.svg?branch=master)](https://travis-ci.com/jwkvam/celluloid)\n[![codecov](https://codecov.io/gh/jwkvam/celluloid/branch/master/graph/badge.svg)](https://codecov.io/gh/jwkvam/celluloid)\n[![pypi](https://badge.fury.io/py/celluloid.svg)](https://pypi.org/project/celluloid/)\n[![pypi versions](https://img.shields.io/pypi/pyversions/celluloid.svg)](https://pypi.org/project/celluloid/)\n\nEasy Matplotlib Animation\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jwkvam/celluloid/blob/master/examples/sines.py\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/86304/48657442-9c11e080-e9e5-11e8-9f54-f46a960be7dd.gif\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nCreating animations should be easy.\nThis module makes it easy to adapt your existing visualization code to create an animation.\n\n## Install\n\n```\npip install celluloid\n```\n\n## Manual\n\nFollow these steps:\n\n1. Create a matplotlib `Figure` and create a `Camera` from it:\n\n```python\nfrom celluloid import Camera\nfig = plt.figure()\ncamera = Camera(fig)\n```\n\n2. Reusing the figure and after each frame is created, take a snapshot with the camera.\n\n```python\nplt.plot(...)\nplt.fancy_stuff()\ncamera.snap()\n```\n\n3. After all frames have been captured, create the animation.\n\n```python\nanimation = camera.animate()\nanimation.save('animation.mp4')\n```\n\nThe entire [module](https://github.com/jwkvam/celluloid/blob/master/celluloid.py) is less than 50 lines of code.\n\n### Viewing in Jupyter Notebooks\n\nView videos in notebooks with [IPython](https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#IPython.display.HTML).\n\n```python\nfrom IPython.display import HTML\nanimation = camera.animate()\nHTML(animation.to_html5_video())\n```\n\n## Examples\n\n### Minimal\n\nAs simple as it gets.\n\n```python\nfrom matplotlib import pyplot as plt\nfrom celluloid import Camera\n\nfig = plt.figure()\ncamera = Camera(fig)\nfor i in range(10):\n    plt.plot([i] * 10)\n    camera.snap()\nanimation = camera.animate()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jwkvam/celluloid/blob/master/examples/simple.py\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/86304/48666133-66660980-ea70-11e8-9024-b167c21a5e83.gif\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n### Subplots\n\nAnimation at the top.\n\n```python\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom celluloid import Camera\n\nfig, axes = plt.subplots(2)\ncamera = Camera(fig)\nt = np.linspace(0, 2 * np.pi, 128, endpoint=False)\nfor i in t:\n    axes[0].plot(t, np.sin(t + i), color='blue')\n    axes[1].plot(t, np.sin(t - i), color='blue')\n    camera.snap()\nanimation = camera.animate()\n```\n\n### Images\n\nDomain coloring example.\n\n```python\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom matplotlib.colors import hsv_to_rgb\n\nfrom celluloid import Camera\n\nfig = plt.figure()\ncamera = Camera(fig)\n\nfor a in np.linspace(0, 2 * np.pi, 30, endpoint=False):\n    x = np.linspace(-3, 3, 800)\n    X, Y = np.meshgrid(x, x)\n    x = X + 1j * Y\n    y = (x ** 2 - 2.5) * (x - 2.5 * 1j) * (x + 2.5 * 1j) \\\n        * (x - 2 - 1j) ** 2 / ((x - np.exp(1j * a)) ** 2\n        * (x - np.exp(1j * 2 * a)) ** 2)\n\n    H = np.angle(y) / (2 * np.pi) + .5\n    r = np.log2(1. + np.abs(y))\n    S = (1. + np.abs(np.sin(2. * np.pi * r))) / 2.\n    V = (1. + np.abs(np.cos(2. * np.pi * r))) / 2.\n\n    rgb = hsv_to_rgb(np.dstack((H, S, V)))\n    ax.imshow(rgb)\n    camera.snap()\nanimation = camera.animate()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jwkvam/celluloid/blob/master/examples/complex.py\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/86304/48747098-f483f080-ec26-11e8-9734-c409e9b0c9ec.gif\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n### Legends\n\n```python\nimport matplotlib\nfrom matplotlib import pyplot as plt\nfrom celluloid import Camera\n\nfig = plt.figure()\ncamera = Camera(fig)\nfor i in range(5):\n    t = plt.plot(range(i, i + 5))\n    plt.legend(t, [f'line {i}'])\n    camera.snap()\nanimation = camera.animate()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jwkvam/celluloid/blob/master/examples/legends.py\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/86304/48750564-9100bf80-ec34-11e8-87fb-bc5c7ddcc6e7.gif\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Limitations\n\n- The axes' limits should be the same for all plots. The limits of the animation will be the limits of the final plot.\n- Legends will accumulate from previous frames. Pass the artists to the [`legend`](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.legend.html) function to draw them separately.\n- [Animating the title does not work](https://stackoverflow.com/questions/47421486/matplotlib-artist-animation-title-or-text-not-changing). As a workaround you can create a text object:   \n```python\nax.text(0.5, 1.01, 'computed title', transform=ax.transAxes)\n```\n- This can demand a lot of memory since it uses [`ArtistAnimation`](https://matplotlib.org/api/_as_gen/matplotlib.animation.ArtistAnimation.html) under the hood. This means that all artists are saved to memory before the animation is constructed.\n- This is a black box. If you want to understand how matplotlib animations work, using this library may hinder you. If you want to be an expert matplotlib user, you may want to pass on this library.\n\n## Credits\n\nInspired by [plotnine](https://github.com/has2k1/plotnine/blob/master/plotnine/animation.py).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwkvam%2Fcelluloid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwkvam%2Fcelluloid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwkvam%2Fcelluloid/lists"}