6.4 KiB
6.4 KiB
| name | description |
|---|---|
| plot_pub | 出版级 matplotlib 绘图(论文 / 报告 / 申报书用,中文字体 + viridis 配色 + dpi 设定一键到位)。✅ 触发:用户要画 XRD 谱、TG-DSC 曲线、应力-应变曲线、SEM 标注、多 panel 学术图、要 SVG/PDF 矢量图给论文。⛔ 不触发:PPT 内嵌图(走 `ppt` skill 的 matplotlib 配图流程);只要快速看一眼数据(直接 `df.plot()` 即可,不用本 skill)。 |
plot_pub
服务建材院的论文 / 申报书 / 调研报告出图。核心是 apply_pub_style() 一键设置 rcParams(中文字体、viridis 默认、字号、dpi、矢量优先),避免每次手动设置十几行还忘配中文字体。
何时用
- 写论文要投 Cement and Concrete Research / J. Am. Ceram. Soc. / Construction and Building Materials 等期刊
- 报告 / 申报书要中文标题 + 中文图例的高 dpi 图
- 多组样本数据对比(XRD 多谱叠图、强度发展曲线、温度场)
- 双 Y 轴(TG-DSC 是典型)
何时不用
- PPT 里要嵌图 → 走
skills/ppt(那边已经有配色 / 尺寸规范) - 交互式探查数据 → 用 plotly / 直接 jupyter
- 只要看趋势不出版 →
df.plot()一行搞定,不用本 skill 的 ceremony
准备
from skills.plot_pub.style import apply_pub_style
import matplotlib.pyplot as plt
import numpy as np
apply_pub_style() # 调一次,后面所有 plt 都按这个 style
apply_pub_style() 参数
| 参数 | 默认 | 说明 |
|---|---|---|
chinese |
True |
加载 SimHei / Microsoft YaHei,中文不显示方块 |
dpi |
150 |
屏幕显示 dpi;保存图用 savefig(..., dpi=300) 单独控 |
font_size |
10 |
论文双栏图标准字号 |
linewidth |
1.2 |
线粗,出版图细些显精致 |
cmap |
"viridis" |
默认 colormap,审稿人不会喷(jet 现在是雷区) |
典型工作流
A. XRD pattern(多相叠图 + 标峰)
from skills.plot_pub.style import apply_pub_style
import matplotlib.pyplot as plt
import numpy as np
apply_pub_style()
fig, ax = plt.subplots(figsize=(6, 4))
# 实测谱
ax.plot(two_theta_exp, intensity_exp, "k-", lw=1.0, label="实测")
# 理论谱(各物相,用 pymatgen XRDCalculator 算的)
for phase, pattern in pymatgen_patterns.items():
ax.vlines(pattern.x, 0, pattern.y / pattern.y.max() * intensity_exp.max() * 0.3,
label=phase, alpha=0.7)
ax.set_xlabel(r"$2\theta$ / °")
ax.set_ylabel("强度 / a.u.")
ax.set_xlim(5, 80)
ax.legend(frameon=False, loc="upper right")
fig.tight_layout()
fig.savefig("xrd_compare.pdf", bbox_inches="tight") # PDF 矢量,期刊偏好
fig.savefig("xrd_compare.png", dpi=300, bbox_inches="tight") # PNG 给 PPT
plt.close(fig) # 关键!run_python 多任务下不关会堆 figure 泄漏内存
B. TG-DSC 双 Y 轴
fig, ax_tg = plt.subplots(figsize=(6, 4))
ax_dsc = ax_tg.twinx()
ax_tg.plot(T, tg_mass, "b-", lw=1.2, label="TG")
ax_dsc.plot(T, dsc_flow, "r-", lw=1.2, label="DSC")
ax_tg.set_xlabel("温度 / °C")
ax_tg.set_ylabel("质量 / %", color="b")
ax_dsc.set_ylabel("热流 / mW·mg$^{-1}$", color="r")
ax_tg.tick_params(axis="y", labelcolor="b")
ax_dsc.tick_params(axis="y", labelcolor="r")
# 合并两个 ax 的 legend
lines1, labels1 = ax_tg.get_legend_handles_labels()
lines2, labels2 = ax_dsc.get_legend_handles_labels()
ax_tg.legend(lines1 + lines2, labels1 + labels2, loc="best", frameon=False)
fig.tight_layout()
fig.savefig("tg_dsc.pdf", bbox_inches="tight")
plt.close(fig)
C. 多组样本对比(强度发展曲线)
fig, ax = plt.subplots(figsize=(6, 4))
ages = [3, 7, 14, 28, 56, 90]
# 用 viridis 给多个样本上色,顺序色觉友好
import matplotlib.cm as cm
colors = cm.viridis(np.linspace(0.1, 0.9, len(samples)))
for (label, strengths), c in zip(samples.items(), colors):
ax.plot(ages, strengths, "o-", color=c, lw=1.2, ms=5, label=label)
ax.set_xlabel("龄期 / d")
ax.set_ylabel("抗压强度 / MPa")
ax.set_xscale("log") # 龄期用对数刻度更清楚
ax.legend(frameon=False)
ax.grid(True, ls="--", alpha=0.3)
fig.tight_layout()
fig.savefig("strength_dev.pdf", bbox_inches="tight")
plt.close(fig)
D. 多 panel(2×2 figure,论文 figure 1 标配)
fig, axes = plt.subplots(2, 2, figsize=(10, 7), constrained_layout=True)
axes[0, 0].plot(...) # (a) XRD
axes[0, 1].plot(...) # (b) FTIR
axes[1, 0].plot(...) # (c) TG
axes[1, 1].plot(...) # (d) 强度
# 子图编号(论文图 1 标准做法)
for ax, letter in zip(axes.flat, "abcd"):
ax.text(0.02, 0.95, f"({letter})", transform=ax.transAxes,
fontweight="bold", va="top")
fig.savefig("fig1_characterization.pdf", bbox_inches="tight")
plt.close(fig)
中文字体配置(Windows 注意)
apply_pub_style(chinese=True) 默认按以下顺序找字体:
SimHei(Windows 自带,黑体)Microsoft YaHei(Windows 自带,雅黑)WenQuanYi Micro Hei(Linux 兜底)
都没有 → 退回 DejaVu Sans,中文显示方块。装字体方式:Windows 控制面板 → 字体,丢 .ttf 进去。
LaTeX 公式渲染:matplotlib 用 $...$ 自动走 mathtext,中英文混排正常。要更精细的 LaTeX(自定义 macro)就 plt.rcParams["text.usetex"] = True,但要本地装 TeX Live。
反模式
- 用 pyplot 状态机不用 OO 接口 —— 写
plt.plot(); plt.xlabel(...)一时爽,多 figure 时变量乱;一律fig, ax = plt.subplots() - 不 close figure ——
run_python跑多次会堆 figure 内存涨,必须plt.close(fig)收尾 - 用 jet colormap —— 色觉障碍审稿人会喷,近年期刊都偏 viridis / plasma / cividis
- 保存图不
bbox_inches="tight"—— legend / 标题被裁掉,反复看图反复改尺寸 - 同图 dpi 跟 figsize 不匹配 —— figsize=(10,7) dpi=300 给 PPT 嵌入太大,字会很小;论文图 figsize=(6,4) 双栏刚好
- PNG 给论文 —— 期刊要矢量,PDF / SVG / EPS 优先;PNG 只给 PPT / 网页
- 中文显示方块还坚持跑 ——
apply_pub_style()失败会 warn,看到 warning 就停下查字体 - legend 框线 / 灰底 —— 出版图
legend(frameon=False),干净 - 轴标签没单位 ——
"温度"是错的,"温度 / °C"才对(SI 推荐/分隔) ax.set_xticks([1,2,3,...])手动写一堆 —— matplotlib 自动 tick 已经足够,手动覆盖只在特殊场景(对数轴 / 离散类别轴)
依赖
matplotlib 已经在 requirements.txt(>=3.8.0)。本 skill 无新增依赖。