個人 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.