9.7 KiB
9.7 KiB
Python数据图表模块
本模块指导使用Python生成科研论文级别的数据图表。
一、环境要求
1.1 conda环境
默认环境名:research
激活命令:
conda activate research
必需库:
pip install matplotlib seaborn numpy pandas scikit-learn
可选库:
pip install plotly scipy statsmodels
1.2 环境配置
详见 modules/environment-setup.md 获取完整的环境配置指南。
二、图表规范
2.1 分辨率要求
| 用途 | DPI | 说明 |
|---|---|---|
| 期刊投稿 | 300-600 | 大多数期刊要求 |
| 顶刊投稿 | 450+ | Nature/Science等 |
| 屏幕展示 | 150 | PPT/网页 |
| 打印海报 | 300 | A0/A1海报 |
本模块默认使用 450 DPI
2.2 输出格式
每张图同时输出两种格式:
- PNG:位图,适合网页和PPT
- SVG:矢量图,适合期刊投稿和后期编辑
2.3 图表尺寸
| 类型 | 宽度(英寸) | 适用场景 |
|---|---|---|
| 单栏图 | 3.5 | 期刊单栏 |
| 双栏图 | 7.0 | 期刊双栏/全宽 |
| PPT图 | 10.0 | 演示文稿 |
三、顶刊配色方案
3.1 Nature/Science 风格
NATURE_COLORS = ['#2E86AB', '#A23B72', '#F18F01', '#C73E1D', '#95C623']
| 颜色 | 色值 | 用途 |
|---|---|---|
| 深蓝 | #2E86AB | 主色调 |
| 玫红 | #A23B72 | 对比色 |
| 橙色 | #F18F01 | 强调色 |
| 砖红 | #C73E1D | 警示色 |
| 黄绿 | #95C623 | 辅助色 |
3.2 Cell 风格
CELL_COLORS = ['#4E79A7', '#F28E2B', '#E15759', '#76B7B2', '#59A14F', '#EDC948']
3.3 渐变色系
# 蓝色渐变(适合热力图)
BLUE_GRADIENT = ['#A8DADC', '#6DAEDB', '#457B9D', '#2C5F7C', '#1D3557']
# 红蓝对比(适合正负值)
DIVERGING_COLORS = {
'cold': ['#2166AC', '#4393C3', '#92C5DE', '#D1E5F0'],
'neutral': '#F7F7F7',
'warm': ['#FDDBC7', '#F4A582', '#D6604D', '#B2182B'],
}
3.4 色盲友好配色
COLORBLIND_SAFE = ['#0077BB', '#33BBEE', '#009988', '#EE7733', '#CC3311', '#EE3377']
3.5 配色原则
- ❌ 禁止使用matplotlib默认颜色
- ❌ 禁止使用纯红、纯蓝、纯绿等基础色
- ✅ 同一图中颜色数量控制在5种以内
- ✅ 确保色盲友好(避免红绿直接对比)
- ✅ 使用渐变色表示连续变量
四、代码模板
4.1 基础模板
"""
Figure X: [图表标题]
论文章节: [所属章节]
描述: [图表内容描述]
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
from pathlib import Path
# ============================================================
# 中文字体配置(macOS系统)
# ============================================================
CHINESE_FONT = None
font_candidates = [
'/System/Library/Fonts/STHeiti Light.ttc',
'/System/Library/Fonts/Supplemental/Songti.ttc',
'/Library/Fonts/Songti.ttc',
'/System/Library/Fonts/PingFang.ttc',
]
for fp in font_candidates:
if Path(fp).exists():
CHINESE_FONT = fm.FontProperties(fname=fp)
break
if CHINESE_FONT is None:
plt.rcParams['font.sans-serif'] = ['Heiti TC', 'STHeiti', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# ============================================================
# 顶刊配色
# ============================================================
COLORS = ['#4E79A7', '#F28E2B', '#E15759', '#76B7B2', '#59A14F', '#EDC948']
# ============================================================
# 全局样式设置
# ============================================================
def setup_plot_style():
"""配置全局绑定样式"""
plt.rcParams.update({
'font.family': 'sans-serif',
'font.size': 10,
'axes.titlesize': 12,
'axes.labelsize': 10,
'xtick.labelsize': 9,
'ytick.labelsize': 9,
'legend.fontsize': 9,
'lines.linewidth': 1.5,
'lines.markersize': 6,
'axes.linewidth': 1.0,
'axes.spines.top': False,
'axes.spines.right': False,
'axes.grid': True,
'grid.alpha': 0.3,
'grid.linewidth': 0.5,
'legend.frameon': False,
'savefig.dpi': 450,
'savefig.bbox': 'tight',
'savefig.pad_inches': 0.1,
'figure.facecolor': 'white',
'axes.facecolor': 'white',
})
# ============================================================
# 主绑定代码
# ============================================================
def main():
setup_plot_style()
# === 在此处编写具体绑定代码 ===
fig, ax = plt.subplots(figsize=(7, 5))
# 示例数据
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), color=COLORS[0], label='Model A')
ax.plot(x, np.cos(x), color=COLORS[1], label='Model B')
# 标签设置(中文使用FontProperties)
if CHINESE_FONT:
ax.set_xlabel('时间 (s)', fontproperties=CHINESE_FONT)
ax.set_ylabel('幅值', fontproperties=CHINESE_FONT)
ax.set_title('模型对比', fontproperties=CHINESE_FONT)
ax.legend(prop=CHINESE_FONT)
else:
ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')
ax.set_title('Model Comparison')
ax.legend()
# === 绑定代码结束 ===
# 保存图片
output_dir = Path(__file__).parent
fig_name = Path(__file__).stem
plt.savefig(output_dir / f'{fig_name}.png', dpi=450, format='png')
plt.savefig(output_dir / f'{fig_name}.svg', format='svg')
plt.show()
print(f"图片已保存至: {output_dir}")
if __name__ == '__main__':
main()
4.2 常用图表类型
折线图
fig, ax = plt.subplots(figsize=(7, 5))
for i, (label, data) in enumerate(datasets.items()):
ax.plot(x, data, color=COLORS[i], label=label, linewidth=1.5, marker='o', markersize=4)
ax.set_xlabel('Epoch')
ax.set_ylabel('Accuracy (%)')
ax.legend()
柱状图
fig, ax = plt.subplots(figsize=(7, 5))
x_pos = np.arange(len(categories))
bars = ax.bar(x_pos, values, color=COLORS[:len(categories)], edgecolor='white', linewidth=0.5)
ax.set_xticks(x_pos)
ax.set_xticklabels(categories)
ax.set_ylabel('Performance')
分组柱状图
fig, ax = plt.subplots(figsize=(8, 5))
x = np.arange(len(categories))
width = 0.25
for i, (label, values) in enumerate(groups.items()):
ax.bar(x + i * width, values, width, label=label, color=COLORS[i])
ax.set_xticks(x + width)
ax.set_xticklabels(categories)
ax.legend()
热力图
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(matrix, cmap='RdBu_r', aspect='auto', vmin=-1, vmax=1)
plt.colorbar(im, ax=ax, label='Correlation')
ax.set_xticks(range(len(labels)))
ax.set_xticklabels(labels, rotation=45, ha='right')
ax.set_yticks(range(len(labels)))
ax.set_yticklabels(labels)
箱线图
fig, ax = plt.subplots(figsize=(7, 5))
bp = ax.boxplot(data_list, labels=labels, patch_artist=True)
for patch, color in zip(bp['boxes'], COLORS):
patch.set_facecolor(color)
patch.set_alpha(0.7)
散点图
fig, ax = plt.subplots(figsize=(7, 5))
scatter = ax.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
plt.colorbar(scatter, ax=ax, label='Value')
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
五、文件管理
5.1 目录结构
项目目录/
├── figures/
│ ├── chapter1_introduction/
│ │ ├── fig1_overview.py
│ │ ├── fig1_overview.png
│ │ └── fig1_overview.svg
│ ├── chapter2_method/
│ │ └── ...
│ ├── chapter3_results/
│ │ └── ...
│ └── chapter4_discussion/
│ └── ...
5.2 命名规范
- 文件名格式:
fig{序号}_{描述}.py - 示例:
fig1_model_architecture.py,fig5_accuracy_comparison.py - 输出图片与代码同名,仅扩展名不同
六、执行流程
6.1 标准流程
-
确认conda环境已激活
conda activate research -
创建/编辑Python脚本
- 使用上述模板
- 修改数据和绑定代码
-
运行脚本
python figures/chapter1/fig1_xxx.py -
检查输出
- 确认PNG和SVG都已生成
- 检查图表质量
-
如有错误,修复后重新运行
6.2 缺失库处理
# 使用pip安装
pip install [package_name]
# 或使用conda安装
conda install [package_name]
七、质量检查清单
图表内容
- 数据准确无误
- 坐标轴标签完整(含单位)
- 图例清晰可读
- 标题简洁明了
视觉效果
- 使用顶刊配色方案
- 分辨率达到450 DPI
- 字体大小适中(可读)
- 无多余的网格线或边框
文件输出
- PNG格式已生成
- SVG格式已生成
- 文件命名规范
- 存放在正确目录
八、常见问题
Q1:中文显示为方块
解决方案:
# 方法1:指定字体文件
from matplotlib.font_manager import FontProperties
font = FontProperties(fname='/System/Library/Fonts/STHeiti Light.ttc')
ax.set_xlabel('中文标签', fontproperties=font)
# 方法2:全局设置
plt.rcParams['font.sans-serif'] = ['SimHei', 'Heiti TC', 'STHeiti']
plt.rcParams['axes.unicode_minus'] = False
Q2:图片模糊
解决方案:
plt.savefig('figure.png', dpi=450, bbox_inches='tight')
Q3:颜色不够用
解决方案:
# 使用colormap生成更多颜色
import matplotlib.cm as cm
colors = cm.viridis(np.linspace(0, 1, n_colors))
Q4:图例遮挡数据
解决方案:
ax.legend(loc='upper left', bbox_to_anchor=(1.02, 1))
plt.tight_layout()