make-a-gif


Namemake-a-gif JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
SummaryMake gifs in python.
upload_time2025-07-31 06:30:19
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseMIT License Copyright (c) 2025 John Gardner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords gifs plots images animation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">

# `make-a-gif`

A (very) simple package for generating gifs using `matplotlib`.

<img src="https://github.com/jla-gardner/make-a-gif/raw/main/examples/outputs/noise.gif" width="80%" style="border-radius: 10px;">

</div>

## Installation

```bash
pip install make-a-gif
```

or just copy across the `make_a_gif.py` file to your project.

## Usage

For a full suite of examples, see the [examples](examples) directory - note that 
`make-a-gif` works well with Jupyter notebooks.

```python
import matplotlib.pyplot as plt
from make_a_gif import gif


# define a function that generates a plot for a given frame
def plotting_func(i: int) -> None:
    xs = range(i + 1)
    ys = [x**2 for x in xs]
    plt.plot(xs, ys, "-o", clip_on=False, zorder=10)
    # make sure the limits are always the same
    plt.xlim(0, 10)
    plt.ylim(0, 100)


# create the gif
gif(plotting_func, frames=range(11), fps=2, save_to="squared.gif")
```
<img src="examples/outputs/squared.gif" width="360px">


## Documentation

The only object exported by `make-a-gif` is the `gif` function.

```python
gif(
    frames: Iterable[Frame],
    function: Callable[[Frame], None | str | Path | Figure],
    save_to: str | Path | None = None,
    fps: float = 10,
    css: dict[str, str] | None = None,
    savefig_kwargs: dict[str, Any] | None = None,
) -> HTML | None:
    ...
```

**Description:**

Generate a GIF from a sequence of frames.

Based on the return type of the function, the following happens:
- ``None``: assume that the currently active matplotlib figure has been
  contains the desired image. Use this figure for the next frame, and then
  close the figure.
- ``str`` or ``Path``: assume that this points to an image file.
  This gets used as the next image in the gif.
- ``plt.Figure``: use the current content of the matplotlib figure as the
  next image in the gif. The figure is **not** closed.

The function is called for each frame, and the return values are used
to generate images for the gif in order. In pseudocode:

```python
images = []

for frame in frames:
    ret = function(frame)
    if isinstance(ret, str | Path):
        images.append(Image.open(ret))
    elif isinstance(ret, Figure):
        images.append(ret.savefig())
    elif ret is None:
        images.append(plt.savefig())

return gif(images)
```

**Parameters:**

- `frames` is an iterable of arbitrary objects. These are passed in order,
  and one-by-one to the `function`.
- `function` takes an arbitrary frame object as input, and generates a single
  image for the gif. There are several behaviours here, depending on the return
  type of `function`:
    - `None`: assume that a matplotlib plot has been generated.
      This is then used as the next image in the gif.
      The figure is closed automatically after each frame.
    - `plt.Figure`: uses the current content of the figure as the
      next image in the gif. The figure is **not** closed.
    - `str` or `Path`: assume that this points to an image file.
      This gets used as the next image in the gif.
- `save_to` is the path to save the gif to. If not provided, the gif is not saved.
- `fps` is the frames per second of the gif, by default 10
- `css` is the CSS to apply to the HTML returned by the function.
- `savefig_kwargs` are the keyword arguments to pass to `plt.savefig` when
  saving the figure to a file. The default is `{"bbox_inches": "tight", "transparent": True}`.
- `loop` is the loop mode of the gif:
  - `"infinite"`: loop the gif indefinitely
  - `"once"`: play the gif once
  - `"bounce"`: play the gif forwards and then backwards indefinitely

**Returns:**

`gif` returns an `IPython.display.HTML` object. This contains a base64 encoded
version of the gif, and so is independent of the file system - you can e.g. share
notebooks that display this object as a standalone file and the gif will still
work.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "make-a-gif",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "gifs, plots, images, animation",
    "author": null,
    "author_email": "John Gardner <gardner.john97+dphil@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/25/45/e74f26dd0bde5b25a4e7cf9cf44bf354842a431bc3d1d898bd0d4d4bbeda/make_a_gif-0.2.0.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n\n# `make-a-gif`\n\nA (very) simple package for generating gifs using `matplotlib`.\n\n<img src=\"https://github.com/jla-gardner/make-a-gif/raw/main/examples/outputs/noise.gif\" width=\"80%\" style=\"border-radius: 10px;\">\n\n</div>\n\n## Installation\n\n```bash\npip install make-a-gif\n```\n\nor just copy across the `make_a_gif.py` file to your project.\n\n## Usage\n\nFor a full suite of examples, see the [examples](examples) directory - note that \n`make-a-gif` works well with Jupyter notebooks.\n\n```python\nimport matplotlib.pyplot as plt\nfrom make_a_gif import gif\n\n\n# define a function that generates a plot for a given frame\ndef plotting_func(i: int) -> None:\n    xs = range(i + 1)\n    ys = [x**2 for x in xs]\n    plt.plot(xs, ys, \"-o\", clip_on=False, zorder=10)\n    # make sure the limits are always the same\n    plt.xlim(0, 10)\n    plt.ylim(0, 100)\n\n\n# create the gif\ngif(plotting_func, frames=range(11), fps=2, save_to=\"squared.gif\")\n```\n<img src=\"examples/outputs/squared.gif\" width=\"360px\">\n\n\n## Documentation\n\nThe only object exported by `make-a-gif` is the `gif` function.\n\n```python\ngif(\n    frames: Iterable[Frame],\n    function: Callable[[Frame], None | str | Path | Figure],\n    save_to: str | Path | None = None,\n    fps: float = 10,\n    css: dict[str, str] | None = None,\n    savefig_kwargs: dict[str, Any] | None = None,\n) -> HTML | None:\n    ...\n```\n\n**Description:**\n\nGenerate a GIF from a sequence of frames.\n\nBased on the return type of the function, the following happens:\n- ``None``: assume that the currently active matplotlib figure has been\n  contains the desired image. Use this figure for the next frame, and then\n  close the figure.\n- ``str`` or ``Path``: assume that this points to an image file.\n  This gets used as the next image in the gif.\n- ``plt.Figure``: use the current content of the matplotlib figure as the\n  next image in the gif. The figure is **not** closed.\n\nThe function is called for each frame, and the return values are used\nto generate images for the gif in order. In pseudocode:\n\n```python\nimages = []\n\nfor frame in frames:\n    ret = function(frame)\n    if isinstance(ret, str | Path):\n        images.append(Image.open(ret))\n    elif isinstance(ret, Figure):\n        images.append(ret.savefig())\n    elif ret is None:\n        images.append(plt.savefig())\n\nreturn gif(images)\n```\n\n**Parameters:**\n\n- `frames` is an iterable of arbitrary objects. These are passed in order,\n  and one-by-one to the `function`.\n- `function` takes an arbitrary frame object as input, and generates a single\n  image for the gif. There are several behaviours here, depending on the return\n  type of `function`:\n    - `None`: assume that a matplotlib plot has been generated.\n      This is then used as the next image in the gif.\n      The figure is closed automatically after each frame.\n    - `plt.Figure`: uses the current content of the figure as the\n      next image in the gif. The figure is **not** closed.\n    - `str` or `Path`: assume that this points to an image file.\n      This gets used as the next image in the gif.\n- `save_to` is the path to save the gif to. If not provided, the gif is not saved.\n- `fps` is the frames per second of the gif, by default 10\n- `css` is the CSS to apply to the HTML returned by the function.\n- `savefig_kwargs` are the keyword arguments to pass to `plt.savefig` when\n  saving the figure to a file. The default is `{\"bbox_inches\": \"tight\", \"transparent\": True}`.\n- `loop` is the loop mode of the gif:\n  - `\"infinite\"`: loop the gif indefinitely\n  - `\"once\"`: play the gif once\n  - `\"bounce\"`: play the gif forwards and then backwards indefinitely\n\n**Returns:**\n\n`gif` returns an `IPython.display.HTML` object. This contains a base64 encoded\nversion of the gif, and so is independent of the file system - you can e.g. share\nnotebooks that display this object as a standalone file and the gif will still\nwork.\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2025 John Gardner  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "Make gifs in python.",
    "version": "0.2.0",
    "project_urls": {
        "Homepage": "https://github.com/jla-gardner/make-a-gif"
    },
    "split_keywords": [
        "gifs",
        " plots",
        " images",
        " animation"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5f350d3ef734756fdd021a3875c6626d16d94f427546ccd2c26e5675befc8e53",
                "md5": "703d562d95ecbc58608e2b3f397c11b7",
                "sha256": "23348fd729933e9ba86b46aab9ec6abbd0abe150f4ab5ca3de71a9ad89b34723"
            },
            "downloads": -1,
            "filename": "make_a_gif-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "703d562d95ecbc58608e2b3f397c11b7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 6639,
            "upload_time": "2025-07-31T06:30:18",
            "upload_time_iso_8601": "2025-07-31T06:30:18.358381Z",
            "url": "https://files.pythonhosted.org/packages/5f/35/0d3ef734756fdd021a3875c6626d16d94f427546ccd2c26e5675befc8e53/make_a_gif-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2545e74f26dd0bde5b25a4e7cf9cf44bf354842a431bc3d1d898bd0d4d4bbeda",
                "md5": "9afaa777107fba6dfadd625cb38f7f08",
                "sha256": "deefd23ee979ea5b6d95e45a92caf84ae9bf7358cc3e02dd345852062ba2c541"
            },
            "downloads": -1,
            "filename": "make_a_gif-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "9afaa777107fba6dfadd625cb38f7f08",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 5505,
            "upload_time": "2025-07-31T06:30:19",
            "upload_time_iso_8601": "2025-07-31T06:30:19.229673Z",
            "url": "https://files.pythonhosted.org/packages/25/45/e74f26dd0bde5b25a4e7cf9cf44bf354842a431bc3d1d898bd0d4d4bbeda/make_a_gif-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-31 06:30:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "jla-gardner",
    "github_project": "make-a-gif",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "make-a-gif"
}
        
Elapsed time: 1.93410s