个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗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.
pip install memeplotlib
# or
conda install -c brianckeegan -c conda-forge memeplotlib
For the Model Context Protocol server (use memes from Claude Desktop / Claude Code / any MCP client):
pip install "memeplotlib[mcp]"
import memeplotlib as memes
fig, ax = memes.meme("buzz", "memes", "memes everywhere")
fig.savefig("buzz.png")
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.
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")
Object-oriented Meme builder, chainable:
from memeplotlib import Meme
Meme("buzz").top("python").bottom("python everywhere").save("buzz.png")
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")
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
Forward **kwargs to Axes.text:
memes.meme("buzz", "rotated", rotation=15, alpha=0.8)
Alt text for screen readers: every render gets a description built from the template and captions, embedded in saved PNG/SVG/PDF files:
fig, ax = memes.meme("buzz", "memes", "memes everywhere", savefig="buzz.png")
memes.get_alt_text(fig)
# 'Meme using the "Buzz Lightyear" template. Top text: "memes". Bottom text: "memes everywhere".'
memes.meme("buzz", "memes", alt_text="Buzz Lightyear pointing at memes everywhere")
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.matplotlib — when **text_kwargs (e.g. rotation, alpha) are
passed, since only Axes.text can apply them.pillow — for custom local images / arbitrary URLs, or when any of
the other client-only features above 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")
# Axes.text kwargs select the matplotlib path automatically:
memes.meme("buzz", "rotated", rotation=15, alpha=0.8)
See docs/url_construction.rst for the full
memegen URL grammar — escape table, query parameters, font / style / overlay
reference — adapted from jacebrowning/memegen #993.
pip install "memeplotlib[mcp]"
memeplotlib-mcp # boot the MCP server (stdio)
memeplotlib meme buzz "hello" "world" -o /tmp/hello.png # 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.
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
/templates/, /templates/<id>); blank backgrounds and rendered memes alike are cached on disk./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.PIL.ImageDraw using stroke-aware text rendering and a shrink-to-fit loop, and the composed RGBA array is imshown.Axes.text plus patheffects.Stroke for the classic outlined look.ax=None, **kwargs forwarding, and (fig, ax) returns are modeled on
seaborn.matplotlib >= 3.8numpy, requests, Pillow, platformdirsRequires Python 3.10+.
MIT. The bundled Anton font is licensed under the SIL Open Font License v1.1.