← Back to skills
extension
Category: Data & AnalyticsNo API key required

ZP咨询可视化工具

ZP 咨询风格图表生成(matplotlib 输出 PNG)。当用户需要为研究报告/备忘录/汇报材料配图,或提出「ZP 风格图」「咨询风格图表」「出一张图」「做成图片」「可视化成图」「量级对照图」「方法对比卡」「瀑布图」「桥图」「CAGR 箭头」等需求时使用。输出符合品牌规范的图片:主蓝 #0064A7 系配色、中文楷体 + 数字/西文 Arial、白底 180/300dpi、深蓝加粗结论式标题、图底灰色来源行;内置 10 个可整段复制的配方(趋势柱状、双轴柱线、占比堆叠、分组对比、环形图、三联小图、量级悬殊直接标注、三栏方法对比卡、瀑布桥图、CAGR 增长箭头),构件对齐 think-cell 图表规范,数字格式与轴处理对齐 ZP 官方 PPT 模板实测(柱状图数值轴隐藏靠标签读数、千分位、负数 "-" 前缀)。附出图质检链路:数据画像 → 重叠/规范双检(ERROR/WARN)→ 事实卡。不做折断轴(量级悬殊用全量程直接标注)。

personAuthor: user_ffc37972hubcommunity

zp-chart — ZP 咨询风格图表(matplotlib → PNG)

用途:把数据渲染成 ZP 品牌规范的 PNG 配图,风格与既有报告图完全一致。同事拿到脚本改数据即可复用,无需重新调样式。

产物:白底 PNG(默认 180 dpi,可 300 高清)、中文楷体 + 数字 Arial、ZP 全套配色、结论式标题、图底灰色来源行。页脚不放右下角「ZP · 项目」署名(团队约定)。


一、何时用 / 何时不用(与 zp-deck 的分工)

| 场景 | 用什么 | |---|---| | 标准柱 / 线 / 饼,客户要在 PowerPoint 里改数据 | zp-deck(python-pptx 原生可编辑图表) | | 量级悬殊对照、三栏方法对比卡、复杂箭头/倍数标注等定制图 | 本 skill(PNG) | | 报告 / 研究材料 / 备忘录配图,要求 ZP 品牌规范 | 本 skill(PNG) | | 真折断轴(断轴)图表 | 不做——matplotlib 双面板手拼的切口与轴刻度无法对齐(2026-09-16 决策);可编辑的真折断走 zp-deck 的 think-cell | | 网页交互可视化 | 不用本 skill,走 HTML |

选错工具会重复造轮子,或给客户一张改不了的图。

二、环境准备(一次性,约 1 分钟)

Windows 受管 Python 默认不带 matplotlib,装进隔离 venv(不要装全局):

$venv = "$env:USERPROFILE\.workbuddy\binaries\python\envs\default"
if (-not (Test-Path "$venv\Scripts\python.exe")) {
  $py = (Get-ChildItem "$env:USERPROFILE\.workbuddy\binaries\python\versions" -Directory | Select-Object -First 1).FullName + "\python.exe"
  & $py -m venv $venv
}
& "$venv\Scripts\pip.exe" install matplotlib

之后所有脚本用 & "$venv\Scripts\python.exe" 脚本.py 运行。Mac/Linux 直接 pip3 install matplotlib。 仅依赖 matplotlib,无其他包。

三、最快上手(两条路)

想先看长什么样:跑样式总览,一次画全 6 个基础配方(1–6)+ 负向红(输出到 预览目录):

& "$venv\Scripts\python.exe" "$env:USERPROFILE\.workbuddy\skills\zp-chart\scripts\example_gallery.py" "预览目录"

直接改数据用:复制 scripts/example_tam_compare.py(方法对比卡 + 量级悬殊直接标注)或 scripts/example_waterfall_cagr.py(瀑布桥图 + CAGR 箭头),只改顶部「数据区」。

从零写一张最小图(含完整质检链路):

import sys
sys.path.insert(0, r"C:\Users\<user>\.workbuddy\skills\zp-chart\scripts")
from zp_style import *
setup()                                    # ⚠ 必调:字体链/负号/日志

vals = [35, 57, 44]
data_profile('发射次数', vals, unit='次')   # ① 出图前画像:数量/缺失/悬殊比 → 配方建议
fig, ax = plt.subplots(figsize=(8.4, 3.7))
bars = ax.bar(['2025 上半年', '2025 下半年', '2026 上半年'], vals,
              color=[LBLUE, BLUE, CYAN], width=0.5, zorder=3, edgecolor='white', lw=1.2)
bar_labels(bars, [fmt_num(v) for v in vals], fontsize=12)   # 千分位标签
ax.set_ylim(0, 72)
style(ax, title='下半年比上半年多 63%(单位:次)', yaxis=False)   # 柱状图隐藏数值轴
source_note(fig, '数据来源:×××')                          # 图底来源行,必须有
p = save(fig, 'demo.png', outdir='figs')                   # ② 默认 180 dpi;300 加 dpi=300
write_facts(p, title='标题写结论,不写名词',                    # ③ 事实卡:图内数字唯一可引用来源
            series={'发射次数(次)': vals}, source='数据来源:×××')

出图后跑一遍质检(重叠 ERROR + 规范 WARN,详见「四」末节):

& "$venv\Scripts\python.exe" "$env:USERPROFILE\.workbuddy\skills\zp-chart\scripts\check_overlap.py" "你的脚本.py" "预览目录"

四、API 速查(zp_style,from zp_style import * 全部带出)

| 函数 / 常量 | 作用 | 关键点 | |---|---|---| | setup() | 全局字体与 rcParams | 每个脚本开头必调一次;字体链见「排障」第 1 条 | | style(ax, ylab, title, grid, yaxis) | 清理坐标轴 + 结论式标题 | 去上右边框、浅灰网格置底;标题传结论句;yaxis=False 隐藏数值轴(刻度+左框线,保留主网格)——柱状/条形图默认这么用,单位并入标题 | | fmt_num(v, nd, unit) | 千分位数字标签 | fmt_num(114000)→114,000;负数普通连字符(模板 #,##0 规范) | | bar_labels(bars, texts, inside, dy, fontsize) | 柱数值标签 | inside=True 标柱内并按柱色自动选白/深蓝字 | | save(fig, name, outdir, dpi) | 存 PNG | 白底、紧裁边、打印路径并返回;dpi=300 出高清 | | figsize('full'\|'half'\|'wide'\|'cards') | 画布预设 | 12.5×5.6 / 5.8×5.0 / 12.0×6.75 / 13.2×5.1,贴 PPT 内容区 | | source_note(fig, text) | 图底左侧来源行 | 必须:数据来源 / 口径说明 / 汇率假设 | | brand_footer(fig, source, logo_path) | 图底页脚 | 只有来源行(+可选 logo);无右下角署名 | | card(ax, hdr, title, subtitle, big, unit, segs, desc) | 三栏方法对比卡单元 | 配 1×3 gridspec 用,详见配方 8 | | waterfall(ax, items, …) | 瀑布图 / 桥图 | items=(标签,值,'total'/'+'/'-');自动连接线+段标签+落地总计;配 grid=False, yaxis=False,详见配方 9 | | cagr_arrow(ax, p0, p1, text, …) | CAGR 增长箭头 | 数据坐标贝塞尔弧+带圈标注;起终点抬到两端标签上方防穿字,详见配方 10 | | data_profile(name, *series, unit, source) | 出图前数据画像(质检①) | 打印 n/缺失/极值/悬殊比 + 配方建议(≥30× → 配方 7 勿折断轴),并返回 dict | | write_facts(png_path, title, series, source, notes) | 事实卡(质检③) | PNG 旁写 <名>.facts.txt:数据+统计+来源+口径,图内数字解读唯一可引用来源 |

颜色常量(对齐 ZP PPT 模板):BLUE #0064A7 主蓝 | LBLUE #BAE3FF 堆叠次要段 | CYAN #31ACFF 对比系列 | DBLUE #00426D 标题/数值标签 | GREEN #00B050 正向对照 | AMBER #FFB400 中性强调 | ORANGE #FF5600 强强调/箭头 | RED #C00000 负向/下跌专用 | GREY #D9D9D9、DGREY 来源行、GRID/SPINE 网格线。

出图质检链路(三步:画像 → 双检 → 事实卡)

| 步 | 工具 | 作用 | |---|---|---| | ① 出图前 | data_profile() | 数据画像:数量/缺失/极值/悬殊比 → 配方建议(≥30× 提示走配方 7、含负值提示走瀑布图、0–1 提示按百分比) | | ② 出图后 | check_overlap.py <脚本.py> [输出目录] | ERROR:文本×文本 / 线·箭头×文本 像素级重叠;WARN:品牌色板外颜色、字号 <8pt、缺来源行、英文单位、负号格式(U+2212/括号负数)、负数用非 RED 强调色、文字越出画布 | | ③ 出图后 | write_facts() | 事实卡 <名>.facts.txt:数据(千分位)+ 统计 + 来源行 + 口径备注,作为图内数字解读的唯一可引用来源(写报告引用数字一律以此为准) |

约定:ERROR 必改;WARN 逐条判断(有些是刻意的)。退出码:有 ERROR 时 check_overlap.py 返回 1,可串进批处理。当前基线:example_gallery.py / example_tam_compare.py / example_waterfall_cagr.py 共 6 张图 0 ERROR / 0 WARN。

五、硬规则(团队约定,不可违反)

  1. 中文报告图内禁止英文单位:不写 RMB/USD/bn/k,写 亿元、万亿美元、户、颗、次。
  2. 敏感测算数字对外模糊成区间(如 8,000–9,000 亿元):柱画中点、标签标区间。
  3. 数据先查原表(年报附录/券商底稿/官方统计),不估算;图底必须标来源。
  4. 汇率换算只作量级参考,须在图内注明(如 1≈7.1)。
  5. 口径保密的测算不画公式推导,用 card 的定性占比条替代。
  6. 负向 / 下跌数值统一用 RED(如同比 -39%);ORANGE/AMBER 不表示负向。
  7. 数字标签用千分位 fmt_num()(模板数据标签格式 #,##0);负数一律普通连字符 "-" 前缀,禁 U+2212、禁括号负数。
  8. 柱状 / 条形图隐藏数值轴(style(..., yaxis=False))靠数据标签读数,单位并入标题「(单位:××)」或类别轴;折线、双轴、对数、全量程条形图保留数值轴(模板实测口径)。
  9. 来源行以「资料来源:/数据来源:」开头,调研来源带样本量时写 N=xx(如「资料来源:ZP 用户调研,N=20」);单色系列用主蓝,多系列按 蓝 → 灰 → 浅蓝 → 亮蓝 顺序取色。

六、配方索引(10 个,代码见 references/chart_recipes.md,可整段复制)

| # | 配方 | 适用场景 | |---|---|---| | 1 | 趋势柱状 + 数值标签 | 3–5 个期间的数量对比 | | 2 | 双轴柱线(柱=绝对值,线=占比) | 既要看量又要看结构 | | 3 | 占比堆叠柱 | 分期构成拆解 | | 4 | 分组对比柱(可对数刻度) | 两主体多指标对比,量级差大 | | 5 | 环形图(中心放总量) | 集中度,只要一个印象 | | 6 | 三联小图 + 弧线箭头倍数 | 逐组对比并强调倍数 | | 7 | 水平条形 · 全量程直接标注 | 一根大数 + 几根小数的量级悬殊对照(不做折断轴) | | 8 | 三栏方法对比卡 | 几种算法/口径并列,不暴露公式 | | 9 | 瀑布图 / 桥图 | 收入/利润驱动拆解(增减项 + 连接线 + 落地总计) | | 10 | CAGR 增长箭头 | 趋势图上的增长故事(弧线 + 带圈增速) |

配方 7、8 完整范例:scripts/example_tam_compare.py;配方 9、10 完整范例:scripts/example_waterfall_cagr.py;配方 1–6 + 负向红总览:scripts/example_gallery.py。 图表构件(瀑布/箭头/直标)对齐 think-cell 图表规范,规范条文见 chart_recipes.md「十、think-cell 式图表规范」;折断轴已弃用(见该节第 6 条与配方 7 说明);配方 1/3/6 的数值轴处理与数字格式见「十一、ZP 官方模板图表规范实测」。

七、排障速查(症状 → 解法)

| 症状 | 原因与解法 | |---|---| | 汉字全变方框(豆腐块) | 字体链被写到了 font.sans-serif。matplotlib 逐字回退只认 font.family 列表;正确写法 rcParams['font.family'] = ['Arial','KaiTi','STKaiti','SimSun','Microsoft YaHei'](setup() 已内置,别自己改)。症状隐蔽:只报一行 Glyph missing from font(s) Arial,不报错 | | 中文加粗不生效 | 楷体无 bold 字形,回退常规粗细(数字/拉丁仍是 Arial Bold)。PPT 同款观感,属预期,不要换字体 | | 中文负号变方框 | setup() 的 axes.unicode_minus=False 已处理,别删 | | 控制台刷 findfont: Failed to find font weight bold | 同上,属预期;setup() 已把 font_manager 日志降到 ERROR,若仍出现说明没调 setup() | | 保存报 OSError [Errno 22] Invalid argument | 输出文件被预览面板锁定,不是代码问题;输出到新目录再存 | | PowerShell 跑脚本中文乱码 | 脚本开头 sys.stdout.reconfigure(encoding='utf-8')(zp_style 已带) | | fig.text 来源行被裁掉 | save() 的 bbox_inches='tight' 会包住 fig.text;图底文字用 source_note(fig 级)而非 ax.text | | 标签互相压叠 | 双轴图占比标签偏移至少 +6、总计 +5;箭头落点避开柱顶标签;详见 chart_recipes.md「通用坑」末条 | | 量级悬殊对照怎么画(一根大数 + 几根小数) | 不做折断轴(2026-09-16 决策:matplotlib 双面板手拼的切口与轴刻度/面板间隙无法对齐,三轮修复仍出伪影——空白矩形、切口重复、切口与轴不对应)。用配方 7:全量程线性 + 柱尾直接标注;可编辑的真折断走 zp-deck 的 think-cell | | CAGR/弧线箭头与圆圈标注脱节、或弧线下塌穿柱 | 别用 FancyArrowPatch + connectionstyle='arc3':弯拱按显示坐标全位移缩放(rad>0 对右上走向的箭头是向下塌),且控制点按创建时 dpi 烘焙、savefig 换 dpi 后弧线与标注脱节(实测复现)。用 cagr_arrow()——全程数据坐标贝塞尔,任意 dpi 相对位置恒定 | | 隐藏数值轴后,主网格也跟着消失了 | 别用 ax.yaxis.set_visible(False)——Axis.draw 见不可见就提前 return,把该轴的网格线一起干掉(模板要的是「数值轴隐藏 + 主网格保留」)。用 style(ax, yaxis=False):只关刻度线/刻度标签/左框线 | | 质检报出假重叠 / 假越界 | 两种已知情形已修:① style(yaxis=False) 关掉的数值轴刻度标签仍在 Text registry 里;② 超出 xlim/ylim 的刻度(如对数轴低于下限的 10¹)bbox 有坐标但不绘制。若你自建构件又出现假警,检查是不是自己调了 ax.yaxis.set_visible(False) 关轴——改用 style(..., yaxis=False) |

八、文件结构(按需读取,不必全读)

zp-chart/
├── SKILL.md                       # 本文件:选型、API、质检链路、硬规则、排障
├── references/
│   └── chart_recipes.md           # 10 个配方的适用场景 + 可整段复制的代码 + 通用坑
│                                  # + 「十、think-cell 式图表规范」+「十一、ZP 官方模板图表规范实测」
└── scripts/
    ├── zp_style.py                # 样式库(配色/setup/style/保存/标签/card/waterfall/cagr_arrow
    │                              #  + fmt_num / data_profile / write_facts 质检三件套)
    ├── example_gallery.py         # 样式总览:一次画全 6 个基础配方 + 负向红
    ├── example_tam_compare.py     # 完整范例:方法对比卡 + 量级悬殊直接标注(含数据画像示例)
    ├── example_waterfall_cagr.py  # 完整范例:瀑布桥图 + CAGR 增长箭头(改「数据区」即复用)
    └── check_overlap.py           # 出图质检:重叠 ERROR + 规范 WARN 双检
                                   # (python check_overlap.py <出图脚本.py> [输出目录])

九、分享给同事

  • WorkBuddy 用户:把整个 zp-chart 文件夹放到同事的 ~/.workbuddy/skills/ 下自动加载;或直接发打包好的 zp-chart.zip 解压到同一路径。
  • 非 WorkBuddy 用户:拷走 scripts/ 三个 py 当普通脚本用,仅依赖 matplotlib。