General Paint By Py
Overview
本 skill 把一次性的"画一张图"请求,转化为规范、可复现、符合所在仓库输出约定的 matplotlib 绘图脚本,而不是凭记忆即兴写一段无法对齐规格的代码。核心做法:先把用户描述的画面翻译成确定性的数据与规则(并对规则做断言校验),再按既定脚本骨架实现、运行、交付。
生成目标可以是透明 PNG(默认)或不透明白色背景 SVG/PNG(当规格或仓库约定要求时)。在 physics-viz 仓库的 src/math_paper/ 下,必须使用 SVG 预设(见 references/project-conventions.md)。
何时使用
- 用户请求新建图形:从一句描述到包含精确规格的长 prompt 都属于此范围。
- 用户请求修改现有绘图脚本:先完整读取该脚本与其同目录脚本,理解既有结构与约定后再改。
- 规格模糊时不要停下来反复追问:用合理默认值补齐并在回复中注明假设,一次交付、允许按反馈迭代。
工作流
Step 1 — 解析规格,翻译成数据与规则
把画面描述逐条转成程序里的确定性数据,避免在绘制中途"临场发明":
- 布局类:行/列数、网格单元次序、面板数量与并排方式、坐标范围。
- 内容类:哪些对象出现、按什么规则上色/删除线/加粗(分类集合、公式、最小素因子等)。
- 用显式列表/集合/字典常量表达分类,例如"哪些是素数、每类有几个"。
- 凡是有可验证计数的地方(如"共 74 个合数、49 个偶数"),在脚本末尾写
assert,运行即可证明规则被完整实现。 - 把最终规则的要点写进模块 docstring(这也成为后续维护与用户核对时的单一来源)。
Step 2 — 规划版面与层级
在写代码前确定:
- 单面板 or 多面板;多面板时各子图要视觉等宽/等物理尺度。
- 用数据坐标 +
set_aspect("equal")的结构示意(网格、矩形、几何图),还是普通绘图轴(曲线、极坐标)。 - 是否需要坐标轴刻度/边框(示意类图通常
axis("off"),曲线图保留浅色刻度)。 - 元素层级 zorder 习惯:填充 0 → 网格/底图 1 → 主线条 2~3 → 箭头 4 → 点与文字 5+。
- 图例/角注/说明文字的位置与字号;图内文字语言遵循仓库约定(本项目英文)。
Step 3 — 编写绘图脚本
- 按该仓库最接近的既有脚本复制骨架(
build_figure()/main()/if __name__ == "__main__"),只替换面板逻辑,见references/matplotlib-patterns.md的模板。 - 输出配置一律使用共享
Presets,需要微调时用dataclasses.replace,不要手写裸figsize/dpi(见references/project-conventions.md)。 - 段落式注释(
# -- xxx ----)划分逻辑区块;关键常量放在文件顶部集中定义(颜色、尺寸、字体大小)。 - 公式/变量一律用 matplotlib mathtext(
r"$E = kq/r^2$"),不要拼 unicode 数学符号混入正文。
Step 4 — 运行并交付
- 从仓库根执行:
uv run python src/.../xxx.py。 - 脚本无错误地生成文件即视为完成——不要调用任何视觉/看图工具去复查生成的图片,用户会自己查看;只需确认保存路径并报告。
- 除非用户明确要求,不要创建绘图脚本与输出文件之外的额外文件。
Step 5 — 自查(写代码时完成,而非运行后)
assert校验所有可计数规则。- 文字/标注是否可能画出坐标边界(扩展
xlim/ylim或用 offset points 标注)。 - 是否遵守输出背景约定(规格要白色背景必须显式
transparent=False)。 - 运行 lints 并清理新引入错误。
教科书风格图形准则(检查表)
- 干净第一:无阴影、无渐变、无装饰性花边,除非规格明确要求;浅灰细网格线(
#dddddd~`#d5d5d5`)代替深色边框。 - 配色:学术风格常量色即可,保持全图一致。常用:墨色文字
#333/#1a1a1a、深蓝#1f4e9b、亮蓝#2196F3/#2980b9、红#c0392b/#E53935、橙#e67e22、绿#27ae60/#2e8b57、浅灰#999/#888。填充区用同色系淡粉彩(alpha 0.2~0.35 或浅色十六进制)。 - 文字层级:主标签 ≥ 标注 ≈ 图例 > 刻度(如 13 / 10
12 / 89 pt);一致字号,不做花哨字重(粗体只用于强调,如幸存素数)。 - 线宽:主曲线 1.8
2.2,辅助/参考线 0.60.9,边框 0.8~1.6。 - zorder 分层:先画的在底层;显式写 zorder 防止被覆盖(如"删除线压在数字上")。
- 坐标细节:结构图
axis("off")+set_aspect("equal");曲线图去 top/right spine、浅刻度;等比面板用同一物理尺度的坐标范围。 - 图例:手动构造
Line2Dhandles +legend(..., frameon=True, facecolor="white", edgecolor="#cccccc"),比让 matplotlib 推断更可控。 - 不要大标题除非规格要求;图内唯一说明文字一般放图例/角注。
资源
references/matplotlib-patterns.md— 可复用的代码片段库:脚本骨架、多面板、补丁、箭头、删除线/网格、图例、mathtext、刻度、常见坑。写任何绘图代码前先读它。references/project-conventions.md— 本仓库输出约定:目录结构、Preset 选择(math_paper 强制 SVG、其余默认透明 PNG)、背景设置、运行命令。在 physics-viz 里绘图必须先读它。