Skip to main content

Memes with Python's matplotlib

Project description

CI codecov Docs PyPI version conda-forge version Python versions License: MIT

memeplotlib logotype

Memes with Python's matplotlib. Create image-macro memes by either letting the memegen API render them server-side (the default) or falling back to a local Pillow renderer when the API can't express what you want — custom local images, explicit per-line font sizes, custom outlines, or per-line position overrides.

Installation

pip install memeplotlib
# or
conda install -c conda-forge memeplotlib

For the Model Context Protocol server (use memes from Claude Desktop / Claude Code / any MCP client):

pip install "memeplotlib[mcp]"

Quick start

import memeplotlib as memes

fig, ax = memes.meme("buzz", "memes", "memes everywhere")
fig.savefig("buzz.png")

buzz meme example

The function returns (Figure, Axes) — same convention as seaborn, pandas.plot, and other matplotlib extensions. It does not call plt.show() implicitly. Pass show=True if you want auto-display.

Features

Memegen IDs, file paths, or URLs as templates:

memes.meme("drake", "writing tests", "shipping to prod", color="yellow")
memes.meme("/path/to/image.jpg", "top text", "bottom text")
memes.meme("https://example.com/image.png", "from a URL")

drake functional example

Object-oriented Meme builder, chainable:

from memeplotlib import Meme

Meme("buzz").top("python").bottom("python everywhere").save("buzz.png")

buzz OO chained example

Memify existing matplotlib figures:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
memes.memify(fig, "stonks")

memify stonks example

RcParams-style scoped configuration:

with memes.rc_context({"font": "comic", "color": "yellow"}):
    memes.meme("buzz", "scoped style", "no leakage")
# defaults are auto-restored here

# Or set globally:
memes.config["fontsize"] = 96

global configuration example

Forward **kwargs to Axes.text:

memes.meme("buzz", "rotated", rotation=15, alpha=0.8)

Backends

memeplotlib ships three rendering backends. The default "auto" policy picks the best fit; pass backend="..." to override.

Backend What it does Honours
memegen Builds a memegen rendering URL and imshows the response. No client-side text drawing. font, color, style, template_style, width, height, layout, background, overlays, extension (png/jpg/gif/webp)
pillow Downloads the blank, draws captions client-side with PIL.ImageDraw. Used for custom local images and any feature memegen can't express. All caption styling including per-line fontsize, custom outline_color / outline_width, and per-line overrides via Meme.line(...).
matplotlib Legacy: draws captions with Axes.text + patheffects.Stroke. Kept for backwards compatibility. All caption styling plus **kwargs forwarded to Axes.text (e.g. rotation, alpha).

backend="auto" selects:

  • memegen — when the template comes from the memegen catalogue and the caller didn't pass fontsize, a non-default outline_color / outline_width, **text_kwargs, or per-line overrides.
  • pillow — for custom local images / arbitrary URLs, or when any of the above client-only features were requested.
# Default: memegen renders this server-side.
memes.meme("buzz", "memes", "memes everywhere", template_style="default",
           font="impact", width=600)

# Pillow fallback — explicit fontsize forces it.
memes.meme("/path/to/photo.jpg", "top", "bottom", fontsize=48,
           outline_color="red", outline_width=4)

# Per-line overrides force the Pillow backend.
from memeplotlib import Meme
Meme("buzz").top("hi").line(1, "world", fontsize=72, color="yellow").save("out.png")

# Legacy matplotlib path (preserves old behaviour exactly):
memes.meme("buzz", "rotated", rotation=15, alpha=0.8, backend="matplotlib")

See docs/url_construction.rst for the full memegen URL grammar — escape table, query parameters, font / style / overlay reference — adapted from jacebrowning/memegen #993.

Use from agents

pip install "memeplotlib[mcp]"
memeplotlib-mcp                                 # boot the MCP server (stdio)
memeplotlib meme buzz "hello" "world" -o /tmp/  # CLI render

The MCP server exposes meme, search_templates, and list_templates tools. The CLI is useful even without MCP — agent harnesses can shell out, and CI scripts can render directly.

Documentation

Full docs including a tutorial, user guide, conventions reference, and API reference: brianckeegan.github.io/memeplotlib.

Build locally:

pip install -e ".[docs]"
sphinx-build -W docs docs/_build

How it works

  1. Template metadata comes from the memegen API (/templates/, /templates/<id>); blank backgrounds and rendered memes alike are cached on disk.
  2. Memegen backend (default for memegen IDs): a fully-formed rendering URL (/images/<id>/<line_1>/.../<line_n>.<ext>?style=...&font=...) is built via memeplotlib.build_memegen_url. The composed image is fetched and displayed with Axes.imshow.
  3. Pillow backend (default for custom images, or when client-only features are requested): the blank is fetched once, then captions are drawn with PIL.ImageDraw using stroke-aware text rendering and a shrink-to-fit loop, and the composed RGBA array is imshown.
  4. Matplotlib backend (legacy, opt-in): captions are drawn with Axes.text plus patheffects.Stroke for the classic outlined look.
  5. The bundled Anton font (Impact-like, SIL OFL licensed) is used as a fallback for systems where Impact isn't installed.

Related projects

  • matplotlib — the rendering engine.
  • memegen — the template registry and blank-image source (api.memegen.link).
  • seaborn — the API conventions for ax=None, **kwargs forwarding, and (fig, ax) returns are modeled on seaborn.

Dependencies

  • matplotlib >= 3.8
  • numpy, requests, Pillow, platformdirs

Requires Python 3.10+.

License

MIT. The bundled Anton font is licensed under the SIL Open Font License v1.1.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memeplotlib-0.5.0.tar.gz (21.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memeplotlib-0.5.0-py3-none-any.whl (122.7 kB view details)

Uploaded Python 3

File details

Details for the file memeplotlib-0.5.0.tar.gz.

File metadata

  • Download URL: memeplotlib-0.5.0.tar.gz
  • Upload date:
  • Size: 21.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for memeplotlib-0.5.0.tar.gz
Algorithm Hash digest
SHA256 b7cc83cadb05d013fe96315061a1cdcd9893dd84c1e6eab9e27d3458782dc51d
MD5 b60853c61554b970874fb8223b7f9751
BLAKE2b-256 a0f42d372bd637752f57708cdc729c28f6855a6a4d9cd344750760b458bcb768

See more details on using hashes here.

Provenance

The following attestation bundles were made for memeplotlib-0.5.0.tar.gz:

Publisher: publish_pypi.yml on brianckeegan/memeplotlib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file memeplotlib-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: memeplotlib-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 122.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for memeplotlib-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e9d493a489ef268515ded23619c95ad04c4294df59007424d0b6e141f17ee908
MD5 bf14c3304ac18feb30374979d8562ae1
BLAKE2b-256 fba9136d6433887fc2e166a6cc0aa16fb6a1069c4dfde23144725ecefff5b2db

See more details on using hashes here.

Provenance

The following attestation bundles were made for memeplotlib-0.5.0-py3-none-any.whl:

Publisher: publish_pypi.yml on brianckeegan/memeplotlib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page