Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ fig = make_figure(x=x, y=y, title='V-t 实测')
fig.savefig('out.pdf')
```

从 CSV 到投稿前图件自查的完整示例见
[`examples/csv-workflow`](examples/csv-workflow/)。

## 暗色模式(v1.5)

```python
Expand Down
3 changes: 3 additions & 0 deletions docs/quick_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ x, y = load_xy('measurement.csv', x_col='time', y_col='voltage')
fig = make_figure(x=x, y=y, title='V-t 实测')
```

从合成 CSV 数据生成 PNG/PDF 并填写投稿前图件检查报告的完整流程见
[`examples/csv-workflow`](../examples/csv-workflow/)。

**情况 C:MATLAB 端用 Excel**

```matlab
Expand Down
54 changes: 54 additions & 0 deletions examples/csv-workflow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# CSV 到论文图工作流示例

这个示例展示如何从一个干净的 CSV 文件生成投稿前可自查的科研图件。它面向研究生、实验室同学和需要把 Excel/CSV 数据转成论文图的人。

示例边界:

- 数据是合成的,不对应真实实验。
- 脚本只演示图件呈现、导出和检查流程。
- 不处理论文内容判断,不修改实验结论,不替代期刊、学校或导师要求。
- 输出图默认写到本地 `out/` 目录;不要把私有数据或本地路径提交进仓库。

## 文件

| 文件 | 用途 |
|---|---|
| `sample_measurements.csv` | 合成测量数据,包含时间、电压、电流、温度 |
| `plot_csv_workflow.py` | Python 版本,从 CSV 生成双面板图并导出 PNG/PDF |
| `plot_csv_workflow.m` | MATLAB 版本,使用同一份 CSV 生成相同结构图 |
| `submission_check_report.md` | 投稿前图件检查报告模板示例 |

## Python 使用

```bash
python examples/csv-workflow/plot_csv_workflow.py \
--csv examples/csv-workflow/sample_measurements.csv \
--out-dir /tmp/csv-workflow-out
```

生成:

- `/tmp/csv-workflow-out/csv_workflow_voltage_current.png`
- `/tmp/csv-workflow-out/csv_workflow_voltage_current.pdf`

## MATLAB 使用

```matlab
plot_csv_workflow( ...
'examples/csv-workflow/sample_measurements.csv', ...
'/tmp/csv-workflow-out')
```

如果在 Windows 上运行,把输出路径换成自己的临时目录。

## 自查建议

生成图后,按 `submission_check_report.md` 记录:

- 坐标轴单位是否完整。
- 字号、线宽、marker 是否足够清楚。
- PNG 和 PDF 放大后是否清晰。
- 图例是否遮挡数据。
- 导出文件名是否不含本地隐私路径。

这个流程可以反哺 `matlab-figure-ci` 的检查报告,也可以作为“图件投稿前检查资料包”的公开 clean-room 示例。
43 changes: 43 additions & 0 deletions examples/csv-workflow/plot_csv_workflow.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
function fig = plot_csv_workflow(csvPath,outDir)
%PLOT_CSV_WORKFLOW Render a clean-room CSV measurement example.
% fig = PLOT_CSV_WORKFLOW(csvPath,outDir) reads a CSV file with the
% columns time_s, voltage_v, current_a, and temperature_c, then exports a
% two-panel voltage/current figure to PNG and PDF.

if nargin < 1 || isempty(csvPath)
csvPath = fullfile(fileparts(mfilename('fullpath')),'sample_measurements.csv');
end
if nargin < 2 || isempty(outDir)
outDir = fullfile(pwd,'out');
end
if ~exist(outDir,'dir')
mkdir(outDir);
end

T = readtable(csvPath);

fig = figure('Color','w','Units','centimeters','Position',[2 2 8.9 10.7]);
tiledlayout(fig,2,1,'TileSpacing','compact','Padding','compact');

nexttile;
plot(T.time_s,T.voltage_v,'-o','Color',[0 114 178]/255,'LineWidth',1.2,'MarkerSize',4);
ylabel('Voltage (V)');
legend('Voltage','Location','southeast','Box','off');
grid on;
text(0.02,0.92,'(a)','Units','normalized','FontWeight','bold');
set(gca,'FontName','Arial','FontSize',8,'LineWidth',0.75);

nexttile;
plot(T.time_s,T.current_a,'-s','Color',[230 159 0]/255,'LineWidth',1.2,'MarkerSize',4);
xlabel('Time (s)');
ylabel('Current (A)');
legend('Current','Location','southeast','Box','off');
grid on;
text(0.02,0.92,'(b)','Units','normalized','FontWeight','bold');
set(gca,'FontName','Arial','FontSize',8,'LineWidth',0.75);

pngPath = fullfile(outDir,'csv_workflow_voltage_current.png');
pdfPath = fullfile(outDir,'csv_workflow_voltage_current.pdf');
exportgraphics(fig,pngPath,'Resolution',300);
exportgraphics(fig,pdfPath,'ContentType','vector');
end
75 changes: 75 additions & 0 deletions examples/csv-workflow/plot_csv_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""Render a clean-room CSV measurement example as a publication-style figure."""
from __future__ import annotations

import argparse
import csv
from pathlib import Path

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt


def load_measurements(csv_path: Path) -> dict[str, list[float]]:
data = {
"time_s": [],
"voltage_v": [],
"current_a": [],
"temperature_c": [],
}
with csv_path.open(newline="", encoding="utf-8") as handle:
reader = csv.DictReader(handle)
for row in reader:
for key in data:
data[key].append(float(row[key]))
return data


def make_figure(data: dict[str, list[float]]) -> plt.Figure:
plt.rcParams.update({
"font.family": "DejaVu Sans",
"font.size": 8,
"axes.linewidth": 0.8,
"lines.linewidth": 1.4,
})

fig, axes = plt.subplots(2, 1, figsize=(3.5, 4.2), sharex=True, constrained_layout=True)
time_s = data["time_s"]

axes[0].plot(time_s, data["voltage_v"], marker="o", color="#0072B2", label="Voltage")
axes[0].set_ylabel("Voltage (V)")
axes[0].legend(frameon=False, loc="lower right")
axes[0].grid(True, color="#DDDDDD", linewidth=0.6)
axes[0].text(0.02, 0.92, "(a)", transform=axes[0].transAxes, fontweight="bold")

axes[1].plot(time_s, data["current_a"], marker="s", color="#E69F00", label="Current")
axes[1].set_xlabel("Time (s)")
axes[1].set_ylabel("Current (A)")
axes[1].legend(frameon=False, loc="lower right")
axes[1].grid(True, color="#DDDDDD", linewidth=0.6)
axes[1].text(0.02, 0.92, "(b)", transform=axes[1].transAxes, fontweight="bold")

return fig


def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--csv", type=Path, default=Path(__file__).with_name("sample_measurements.csv"))
parser.add_argument("--out-dir", type=Path, default=Path("out"))
args = parser.parse_args()

args.out_dir.mkdir(parents=True, exist_ok=True)
data = load_measurements(args.csv)
fig = make_figure(data)

stem = "csv_workflow_voltage_current"
fig.savefig(args.out_dir / f"{stem}.png", dpi=300)
fig.savefig(args.out_dir / f"{stem}.pdf")
plt.close(fig)
return 0


if __name__ == "__main__":
raise SystemExit(main())
13 changes: 13 additions & 0 deletions examples/csv-workflow/sample_measurements.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
time_s,voltage_v,current_a,temperature_c
0,2.95,0.118,24.8
1,3.02,0.121,24.9
2,3.08,0.126,25.0
3,3.13,0.130,25.2
4,3.17,0.132,25.4
5,3.20,0.135,25.6
6,3.23,0.137,25.7
7,3.25,0.138,25.9
8,3.27,0.139,26.1
9,3.28,0.140,26.2
10,3.29,0.140,26.4
11,3.30,0.141,26.5
33 changes: 33 additions & 0 deletions examples/csv-workflow/submission_check_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# CSV 工作流投稿前检查报告

## 1. 基本信息

| 项目 | 内容 |
|---|---|
| 数据来源 | `sample_measurements.csv`,合成数据 |
| 图件脚本 | `plot_csv_workflow.py` / `plot_csv_workflow.m` |
| 图件类型 | 双面板时间序列图 |
| 输出格式 | PNG + PDF |
| 目标用途 | 投稿前自查示例 |

## 2. 图件检查

| 检查项 | 状态 | 说明 |
|---|---|---|
| 坐标轴单位 | 通过 | 时间、电压、电流均有单位 |
| 字体一致性 | 通过 | 使用统一字体和字号 |
| 线宽与 marker | 通过 | 主线和 marker 在小尺寸下仍可读 |
| 配色 | 通过 | 蓝/橙组合,灰度下仍有差异 |
| 图例位置 | 通过 | 图例位于右下角,不遮挡主要趋势 |
| 导出格式 | 通过 | 同时导出 PNG 和 PDF |
| 数据边界 | 通过 | 使用合成数据,不含私有路径 |

## 3. 可改进项

- 如果用于真实论文,应按目标期刊要求调整单栏或双栏宽度。
- 如果曲线数量增加,应增加线型或 marker 区分,不要只依赖颜色。
- 如果 CSV 来自真实实验,应保留数据处理脚本和版本记录。

## 4. 结论

该示例适合作为 CSV 到投稿前图件自查的 clean-room 最小流程。真实项目仍需要作者按期刊、导师或课题组要求复核。