psyclaw 0.28.1 → 0.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/agents/recommended/catalog.json +1 -1
- package/dist/src/adapters/pi/extension.js +43 -9
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/ars/mode-editor.d.ts +20 -0
- package/dist/src/ars/mode-editor.js +57 -0
- package/dist/src/ars/mode-editor.js.map +1 -0
- package/dist/src/ars/profile.d.ts +4 -1
- package/dist/src/ars/profile.js +23 -6
- package/dist/src/ars/profile.js.map +1 -1
- package/package.json +10 -3
- package/vendor/academic-paper-skills/LICENSE +21 -0
- package/vendor/academic-paper-skills/NOTICE.md +7 -0
- package/vendor/academic-paper-skills/PSYCLAW_SOURCE.json +14 -0
- package/vendor/academic-paper-skills/academic-paper-composer/SKILL.md +840 -0
- package/vendor/academic-paper-skills/academic-paper-composer/references/section_guides.md +675 -0
- package/vendor/academic-paper-skills/academic-paper-composer/references/writing_standards.md +629 -0
- package/vendor/academic-paper-skills/academic-paper-composer/scripts/chapter_quality_check.py +470 -0
- package/vendor/academic-paper-skills/academic-paper-composer/scripts/final_evaluation.py +550 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/SKILL.md +670 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/references/quality_standards.md +336 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/references/search_strategy.md +459 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/scripts/evaluate_samples.py +300 -0
- package/vendor/academic-paper-skills/academic-paper-strategist/scripts/gap_analysis.py +399 -0
- package/vendor/ars/pi/wrapper.js +9 -0
- package/vendor/nature-skills/LICENSE +201 -0
- package/vendor/nature-skills/NOTICE.md +7 -0
- package/vendor/nature-skills/PSYCLAW_SOURCE.json +19 -0
- package/vendor/nature-skills/skills/nature-figure/README.md +107 -0
- package/vendor/nature-skills/skills/nature-figure/README_EN.md +107 -0
- package/vendor/nature-skills/skills/nature-figure/SKILL.md +154 -0
- package/vendor/nature-skills/skills/nature-figure/agents/openai.yaml +4 -0
- package/vendor/nature-skills/skills/nature-figure/evals/evals.json +325 -0
- package/vendor/nature-skills/skills/nature-figure/manifest.yaml +103 -0
- package/vendor/nature-skills/skills/nature-figure/references/ai-graphical-abstract-workflow.md +129 -0
- package/vendor/nature-skills/skills/nature-figure/references/api.md +576 -0
- package/vendor/nature-skills/skills/nature-figure/references/asset-adaptation.md +72 -0
- package/vendor/nature-skills/skills/nature-figure/references/backend-selection.md +118 -0
- package/vendor/nature-skills/skills/nature-figure/references/chart-types.md +348 -0
- package/vendor/nature-skills/skills/nature-figure/references/common-patterns.md +371 -0
- package/vendor/nature-skills/skills/nature-figure/references/demos.md +58 -0
- package/vendor/nature-skills/skills/nature-figure/references/design-theory.md +467 -0
- package/vendor/nature-skills/skills/nature-figure/references/figure-contract.md +122 -0
- package/vendor/nature-skills/skills/nature-figure/references/figure-legend-conventions.md +90 -0
- package/vendor/nature-skills/skills/nature-figure/references/multipanel-evidence-architecture.md +268 -0
- package/vendor/nature-skills/skills/nature-figure/references/nature-2026-observations.md +124 -0
- package/vendor/nature-skills/skills/nature-figure/references/nature-article-requirements.md +149 -0
- package/vendor/nature-skills/skills/nature-figure/references/openrouter-image-generation.md +141 -0
- package/vendor/nature-skills/skills/nature-figure/references/qa-contract.md +344 -0
- package/vendor/nature-skills/skills/nature-figure/references/r-template-index.md +66 -0
- package/vendor/nature-skills/skills/nature-figure/references/r-workflow.md +234 -0
- package/vendor/nature-skills/skills/nature-figure/references/template-catalog.md +33 -0
- package/vendor/nature-skills/skills/nature-figure/references/tutorials.md +260 -0
- package/vendor/nature-skills/skills/nature-figure/requirements.txt +1 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/audit_figure_collisions.py +742 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/audit_panel_alignment.py +933 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/audit_pdf_text.py +152 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/figure_safety.py +50 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/generate_openrouter_schematic.py +260 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/nature_figure_backend.py +93 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/panel_alignment.R +188 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/plot_templates.py +604 -0
- package/vendor/nature-skills/skills/nature-figure/scripts/validate_figure.py +835 -0
- package/vendor/nature-skills/skills/nature-figure/static/core/contract.md +55 -0
- package/vendor/nature-skills/skills/nature-figure/static/core/stance.md +41 -0
- package/vendor/nature-skills/skills/nature-figure/static/fragments/backend/python.md +56 -0
- package/vendor/nature-skills/skills/nature-figure/static/fragments/backend/r.md +63 -0
- package/vendor/nature-skills/skills/nature-figure/tests/test_figure_safety.py +209 -0
- package/vendor/nature-skills/skills/nature-polishing/README.md +58 -0
- package/vendor/nature-skills/skills/nature-polishing/README_EN.md +58 -0
- package/vendor/nature-skills/skills/nature-polishing/SKILL.md +111 -0
- package/vendor/nature-skills/skills/nature-polishing/agents/openai.yaml +4 -0
- package/vendor/nature-skills/skills/nature-polishing/manifest.yaml +101 -0
- package/vendor/nature-skills/skills/nature-polishing/references/latex-layout.md +211 -0
- package/vendor/nature-skills/skills/nature-polishing/references/nat-comms-2025-diction.md +73 -0
- package/vendor/nature-skills/skills/nature-polishing/references/phrasebank-playbook.md +175 -0
- package/vendor/nature-skills/skills/nature-polishing/references/published-article-patterns.md +126 -0
- package/vendor/nature-skills/skills/nature-polishing/references/section-moves.md +252 -0
- package/vendor/nature-skills/skills/nature-polishing/references/style-guardrails.md +94 -0
- package/vendor/nature-skills/skills/nature-polishing/references/writing-strategy.md +160 -0
- package/vendor/nature-skills/skills/nature-polishing/static/core/failure-modes.md +29 -0
- package/vendor/nature-skills/skills/nature-polishing/static/core/output-format.md +21 -0
- package/vendor/nature-skills/skills/nature-polishing/static/core/stance.md +26 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/generic.md +17 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/nat-comms.md +38 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/nat-mach-intell.md +102 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/journal/nature.md +19 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/language/en.md +19 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/language/zh-to-en.md +19 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/algorithmic.md +18 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/hypothesis.md +17 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/methods.md +35 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/research.md +29 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/paper_type/review.md +17 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/abstract.md +26 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/conclusion.md +15 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/discussion.md +48 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/intro.md +33 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/methods.md +26 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/results.md +61 -0
- package/vendor/nature-skills/skills/nature-polishing/static/fragments/section/title.md +17 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/README.md +44 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/README_EN.md +44 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/SKILL.md +196 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/agents/openai.yaml +4 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/manifest.yaml +19 -0
- package/vendor/nature-skills/skills/nature-ref-verifier/references/common-patterns.md +96 -0
- package/vendor/nature-skills/skills/nature-shared/README.md +43 -0
- package/vendor/nature-skills/skills/nature-shared/README_EN.md +43 -0
- package/vendor/nature-skills/skills/nature-shared/SKILL.md +33 -0
- package/vendor/nature-skills/skills/nature-shared/agents/openai.yaml +6 -0
- package/vendor/nature-skills/skills/nature-shared/core/consistency-sweep.md +122 -0
- package/vendor/nature-skills/skills/nature-shared/core/discussion-argument-language.md +192 -0
- package/vendor/nature-skills/skills/nature-shared/core/ethics.md +88 -0
- package/vendor/nature-skills/skills/nature-shared/core/main-text-discipline.md +179 -0
- package/vendor/nature-skills/skills/nature-shared/core/nature-abstract.md +171 -0
- package/vendor/nature-skills/skills/nature-shared/core/nature-introduction.md +164 -0
- package/vendor/nature-skills/skills/nature-shared/core/nature-results-discussion.md +215 -0
- package/vendor/nature-skills/skills/nature-shared/core/paper-type-taxonomy.md +41 -0
- package/vendor/nature-skills/skills/nature-shared/core/reader-workflow.md +21 -0
- package/vendor/nature-skills/skills/nature-shared/core/research-compliance.md +192 -0
- package/vendor/nature-skills/skills/nature-shared/core/terminology-ledger.md +58 -0
- package/vendor/nature-skills/skills/nature-shared/journal-formats/nat-comms.md +139 -0
- package/vendor/nature-skills/skills/nature-shared/journal-formats/nature-machine-intelligence.md +431 -0
- package/vendor/nature-skills/skills/nature-shared/journal-formats/nature.md +313 -0
- package/vendor/nature-skills/skills/nature-shared/manifest.yaml +52 -0
- package/vendor/nature-skills/skills/nature-shared/scripts/check_consistency.py +273 -0
- package/vendor/nature-skills/skills/nature-shared/tests/test_check_consistency.py +63 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Validated Plot Template Catalog
|
|
2
|
+
|
|
3
|
+
Use this catalog after the backend is resolved to Python and after `asset-adaptation.md` confirms that the requested panel matches a template semantically. These templates use only NumPy and Matplotlib, require real CSV input for production, and produce SVG, PDF, 600 dpi TIFF, and a count-based QA JSON record.
|
|
4
|
+
|
|
5
|
+
Run `python scripts/plot_templates.py <subcommand> --help` for the complete interface.
|
|
6
|
+
|
|
7
|
+
| Subcommand | Required CSV shape | Main safeguards |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `volcano` | gene, effect-size, adjusted-p columns | positive p-value check, explicit thresholds, all points retained, large-data rasterization |
|
|
10
|
+
| `roc` | one FPR column plus one or more TPR columns | range check in `[0,1]`, stable FPR sorting, trapezoidal AUC recorded |
|
|
11
|
+
| `dotplot` | row category, column category, size, color | complete category-order validation, no silent category removal |
|
|
12
|
+
| `marginal` | x, y, optional group | preserves all observations, separates 2D joint structure from 1D marginal distributions |
|
|
13
|
+
| `paired` | pair ID, condition, value | exactly two conditions, rejects duplicate or incomplete pairs unless exclusion is explicit |
|
|
14
|
+
|
|
15
|
+
## Production examples
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
python skills/nature-figure/scripts/plot_templates.py volcano \
|
|
19
|
+
--input results.csv --gene-col gene --effect-col log2fc --p-col padj \
|
|
20
|
+
--output figures/volcano
|
|
21
|
+
|
|
22
|
+
python skills/nature-figure/scripts/plot_templates.py roc \
|
|
23
|
+
--input roc.csv --fpr-col fpr --tpr-cols model_a,model_b \
|
|
24
|
+
--output figures/roc
|
|
25
|
+
|
|
26
|
+
python skills/nature-figure/scripts/plot_templates.py dotplot \
|
|
27
|
+
--input markers.csv --row-col cell_type --column-col gene \
|
|
28
|
+
--size-col pct_exp --color-col avg_exp_scaled --output figures/markers
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Never use `--demo` for a manuscript deliverable. It exists only for explicit smoke tests and is marked in the QA JSON. If required numeric data are missing or non-finite, the default is to stop. `--drop-incomplete` is an explicit exception that records exclusion counts; it is not permission to hide scientifically important missingness.
|
|
32
|
+
|
|
33
|
+
The templates do not compute hypothesis tests. Add statistics only after defining the replicate unit, test, assumptions, multiplicity correction, and legend reporting contract.
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# Tutorials — Nature Figure Making
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [Tutorial 1: Grouped bar chart (multi-metric comparison)](#tutorial-1-grouped-bar-chart-multi-metric-comparison)
|
|
6
|
+
- [Tutorial 2: Ablation bar chart (alpha-graduated, horizontal)](#tutorial-2-ablation-bar-chart-alpha-graduated-horizontal)
|
|
7
|
+
- [Tutorial 3: Multi-panel trend with shared legend](#tutorial-3-multi-panel-trend-with-shared-legend)
|
|
8
|
+
- [Tutorial 4: Heatmap with dual colormaps (positive/negative columns)](#tutorial-4-heatmap-with-dual-colormaps-positivenegative-columns)
|
|
9
|
+
- [Related files](#related-files)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
End-to-end walkthroughs for the most common publication figure types.
|
|
13
|
+
All examples use helpers from [api.md](api.md) and patterns from [common-patterns.md](common-patterns.md).
|
|
14
|
+
For the retained third-party demo map, copyright boundary, and original reimplementation guidance, open [demos.md](demos.md).
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Tutorial 1: Grouped bar chart (multi-metric comparison)
|
|
19
|
+
|
|
20
|
+
**Goal**: Several methods compared across multiple metrics. Legend in a dedicated panel.
|
|
21
|
+
When methods belong to related families, use one coherent baseline family plus one coherent hero family.
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
import os
|
|
25
|
+
import numpy as np
|
|
26
|
+
import matplotlib.pyplot as plt
|
|
27
|
+
from matplotlib import gridspec
|
|
28
|
+
|
|
29
|
+
# --- Style ---
|
|
30
|
+
plt.rcParams['font.family'] = 'sans-serif'
|
|
31
|
+
plt.rcParams['font.sans-serif'] = ['Arial']
|
|
32
|
+
plt.rcParams['svg.fonttype'] = 'none'
|
|
33
|
+
plt.rcParams['font.size'] = 24
|
|
34
|
+
plt.rcParams['axes.spines.right'] = False
|
|
35
|
+
plt.rcParams['axes.spines.top'] = False
|
|
36
|
+
plt.rcParams['axes.linewidth'] = 3
|
|
37
|
+
|
|
38
|
+
# --- Data ---
|
|
39
|
+
methods = ['ResNet1d18', 'ResNet1d34', 'ECGFounder', 'CSFM-Tiny', 'CSFM-Base', 'CSFM-Large']
|
|
40
|
+
colors = ['#484878', '#7884B4', '#B4C0E4', '#E4E4F0', '#E4CCD8', '#F0C0CC']
|
|
41
|
+
metrics = ['Metric 1', 'Metric 2', 'Metric 3']
|
|
42
|
+
mean = {
|
|
43
|
+
'Metric 1': np.array([0.81, 0.83, 0.86, 0.89, 0.91, 0.92]),
|
|
44
|
+
'Metric 2': np.array([0.63, 0.67, 0.71, 0.74, 0.77, 0.79]),
|
|
45
|
+
'Metric 3': np.array([0.41, 0.45, 0.49, 0.53, 0.56, 0.58]),
|
|
46
|
+
}
|
|
47
|
+
std = {k: v * 0.03 for k, v in mean.items()} # placeholder
|
|
48
|
+
|
|
49
|
+
# --- Figure ---
|
|
50
|
+
fig = plt.figure(figsize=(28, 6))
|
|
51
|
+
gs = gridspec.GridSpec(1, len(metrics) + 1) # +1 for legend panel
|
|
52
|
+
|
|
53
|
+
handles, labels = None, None
|
|
54
|
+
for col, metric in enumerate(metrics):
|
|
55
|
+
ax = fig.add_subplot(gs[col])
|
|
56
|
+
bars = ax.bar(
|
|
57
|
+
range(len(methods)),
|
|
58
|
+
mean[metric],
|
|
59
|
+
yerr=std[metric],
|
|
60
|
+
capsize=5,
|
|
61
|
+
color=colors,
|
|
62
|
+
label=methods,
|
|
63
|
+
error_kw={'elinewidth': 2, 'capthick': 2},
|
|
64
|
+
)
|
|
65
|
+
if col == 0:
|
|
66
|
+
handles, labels = ax.get_legend_handles_labels()
|
|
67
|
+
ax.set_xticks([])
|
|
68
|
+
y_vals = mean[metric]
|
|
69
|
+
margin = (y_vals.max() - y_vals.min()) * 0.15
|
|
70
|
+
ax.set_ylim([y_vals.min() - margin, y_vals.max() + margin])
|
|
71
|
+
ax.set_ylabel(metric, fontsize=32)
|
|
72
|
+
|
|
73
|
+
# Legend-only panel
|
|
74
|
+
ax_leg = fig.add_subplot(gs[-1])
|
|
75
|
+
ax_leg.legend(handles, labels, fontsize=28, loc='center', frameon=False)
|
|
76
|
+
ax_leg.set_axis_off()
|
|
77
|
+
|
|
78
|
+
fig.tight_layout(pad=2)
|
|
79
|
+
os.makedirs('./figures', exist_ok=True)
|
|
80
|
+
fig.savefig('./figures/comparison.png', dpi=300)
|
|
81
|
+
fig.savefig('./figures/comparison.pdf', dpi=300)
|
|
82
|
+
plt.close(fig)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Tutorial 2: Ablation bar chart (alpha-graduated, horizontal)
|
|
88
|
+
|
|
89
|
+
**Goal**: Same method with components progressively added; alpha encodes completeness.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
import os
|
|
93
|
+
import numpy as np
|
|
94
|
+
import matplotlib.pyplot as plt
|
|
95
|
+
|
|
96
|
+
plt.rcParams['font.family'] = 'sans-serif'
|
|
97
|
+
plt.rcParams['font.sans-serif'] = ['Arial']
|
|
98
|
+
plt.rcParams['svg.fonttype'] = 'none'
|
|
99
|
+
plt.rcParams['font.size'] = 24
|
|
100
|
+
plt.rcParams['axes.spines.right'] = False
|
|
101
|
+
plt.rcParams['axes.spines.top'] = False
|
|
102
|
+
plt.rcParams['axes.linewidth'] = 3
|
|
103
|
+
|
|
104
|
+
configs = ['None', '+ Module A', '+ Module B', '+ Module C', 'Full']
|
|
105
|
+
values = np.array([0.72, 0.78, 0.81, 0.84, 0.88])
|
|
106
|
+
stds = np.array([0.02, 0.02, 0.01, 0.01, 0.01])
|
|
107
|
+
|
|
108
|
+
n = len(configs)
|
|
109
|
+
blue_rgb = (0.215686, 0.458824, 0.729412) # #3775BA
|
|
110
|
+
alphas = np.linspace(0.2, 1.0, n)
|
|
111
|
+
colors = [(blue_rgb[0], blue_rgb[1], blue_rgb[2], a) for a in alphas]
|
|
112
|
+
|
|
113
|
+
fig, ax = plt.subplots(figsize=(12, 6))
|
|
114
|
+
ax.barh(range(n), values, xerr=stds,
|
|
115
|
+
color=colors, ecolor='k', capsize=5)
|
|
116
|
+
ax.set_yticks(range(n))
|
|
117
|
+
ax.set_yticklabels(configs)
|
|
118
|
+
ax.set_xlim([values.min() - 0.05, values.max() + 0.03])
|
|
119
|
+
ax.set_xlabel('Score', fontsize=32)
|
|
120
|
+
|
|
121
|
+
fig.tight_layout(pad=2)
|
|
122
|
+
os.makedirs('./figures', exist_ok=True)
|
|
123
|
+
fig.savefig('./figures/ablation.png', dpi=300)
|
|
124
|
+
plt.close(fig)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Tutorial 3: Multi-panel trend with shared legend
|
|
130
|
+
|
|
131
|
+
**Goal**: Two trend panels (e.g., train/val curves) and a legend-only third panel.
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import os
|
|
135
|
+
import numpy as np
|
|
136
|
+
import matplotlib.pyplot as plt
|
|
137
|
+
|
|
138
|
+
plt.rcParams['font.family'] = 'sans-serif'
|
|
139
|
+
plt.rcParams['font.sans-serif'] = ['Arial']
|
|
140
|
+
plt.rcParams['svg.fonttype'] = 'none'
|
|
141
|
+
plt.rcParams['font.size'] = 15
|
|
142
|
+
plt.rcParams['axes.spines.right'] = False
|
|
143
|
+
plt.rcParams['axes.spines.top'] = False
|
|
144
|
+
plt.rcParams['axes.linewidth'] = 2
|
|
145
|
+
|
|
146
|
+
methods = ['Baseline', 'CSFM-Tiny', 'CSFM-Base', 'CSFM-Large']
|
|
147
|
+
colors = ['#7884B4', '#E4E4F0', '#E4CCD8', '#F0C0CC']
|
|
148
|
+
x = np.arange(0, 100, 5)
|
|
149
|
+
|
|
150
|
+
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
|
|
151
|
+
|
|
152
|
+
for panel_idx, (ax, panel_name) in enumerate(zip(axes[:2], ['Training', 'Validation'])):
|
|
153
|
+
for method, color in zip(methods, colors):
|
|
154
|
+
y = 0.48 + 0.42 * (1 - np.exp(-x / 30)) + np.random.randn(len(x)) * 0.01
|
|
155
|
+
if method == 'Baseline':
|
|
156
|
+
y -= 0.03
|
|
157
|
+
elif method == 'CSFM-Tiny':
|
|
158
|
+
y += 0.00
|
|
159
|
+
elif method == 'CSFM-Base':
|
|
160
|
+
y += 0.02
|
|
161
|
+
elif method == 'CSFM-Large':
|
|
162
|
+
y += 0.03
|
|
163
|
+
ax.plot(x, y, color=color, lw=2.5, marker='o', markersize=6, label=method)
|
|
164
|
+
ax.set_title(panel_name, fontsize=18)
|
|
165
|
+
ax.set_xlabel('Epoch', fontsize=16)
|
|
166
|
+
ax.set_ylabel('Loss', fontsize=16)
|
|
167
|
+
if panel_idx == 0:
|
|
168
|
+
handles, labels = ax.get_legend_handles_labels()
|
|
169
|
+
|
|
170
|
+
# Legend-only panel
|
|
171
|
+
axes[2].legend(handles, labels, fontsize=14, loc='center', frameon=False)
|
|
172
|
+
axes[2].set_axis_off()
|
|
173
|
+
|
|
174
|
+
fig.tight_layout(pad=2)
|
|
175
|
+
os.makedirs('./figures', exist_ok=True)
|
|
176
|
+
fig.savefig('./figures/trends.png', dpi=300)
|
|
177
|
+
fig.savefig('./figures/trends.pdf', dpi=300)
|
|
178
|
+
plt.close(fig)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Tutorial 4: Heatmap with dual colormaps (positive/negative columns)
|
|
184
|
+
|
|
185
|
+
**Goal**: Score matrix where positive = Reds, negative = Blues_r. Cell text auto-contrasted.
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
import os
|
|
189
|
+
import numpy as np
|
|
190
|
+
import matplotlib as mpl
|
|
191
|
+
import matplotlib.pyplot as plt
|
|
192
|
+
|
|
193
|
+
plt.rcParams['font.family'] = 'sans-serif'
|
|
194
|
+
plt.rcParams['font.sans-serif'] = ['Arial']
|
|
195
|
+
plt.rcParams['svg.fonttype'] = 'none'
|
|
196
|
+
plt.rcParams['font.size'] = 16
|
|
197
|
+
plt.rcParams['axes.spines.right'] = False
|
|
198
|
+
plt.rcParams['axes.spines.top'] = False
|
|
199
|
+
plt.rcParams['axes.linewidth'] = 2
|
|
200
|
+
|
|
201
|
+
# matrix: rows = methods, cols = metrics (alternating positive/negative directions)
|
|
202
|
+
methods = ['Method A', 'Method B', 'Method C', 'Method D']
|
|
203
|
+
metrics = ['Score (+)', 'Error (-)', 'F1 (+)', 'Loss (-)']
|
|
204
|
+
matrix = np.array([
|
|
205
|
+
[0.88, 0.12, 0.85, 0.20],
|
|
206
|
+
[0.81, 0.18, 0.78, 0.28],
|
|
207
|
+
[0.75, 0.25, 0.72, 0.35],
|
|
208
|
+
[0.70, 0.30, 0.68, 0.40],
|
|
209
|
+
])
|
|
210
|
+
|
|
211
|
+
fig, ax = plt.subplots(figsize=(10, 6))
|
|
212
|
+
n_rows, n_cols = matrix.shape
|
|
213
|
+
vmin, vmax = matrix.min(0), matrix.max(0)
|
|
214
|
+
|
|
215
|
+
for j in range(n_cols):
|
|
216
|
+
is_positive = (j % 2 == 0)
|
|
217
|
+
cmap = plt.cm.Reds if is_positive else plt.cm.Blues_r
|
|
218
|
+
cmap = cmap.copy()
|
|
219
|
+
norm = mpl.colors.Normalize(
|
|
220
|
+
vmin=0 if is_positive else vmax[j],
|
|
221
|
+
vmax=vmax[j] if is_positive else 0
|
|
222
|
+
)
|
|
223
|
+
ax.imshow(matrix[:, j:j+1], cmap=cmap, norm=norm,
|
|
224
|
+
aspect='auto', extent=[j-0.5, j+0.5, 0, n_rows], origin='lower')
|
|
225
|
+
|
|
226
|
+
for (i, j), val in np.ndenumerate(matrix):
|
|
227
|
+
is_positive = (j % 2 == 0)
|
|
228
|
+
cmap = plt.cm.Reds if is_positive else plt.cm.Blues_r
|
|
229
|
+
norm = mpl.colors.Normalize(vmin=0 if is_positive else vmax[j],
|
|
230
|
+
vmax=vmax[j] if is_positive else 0)
|
|
231
|
+
r, g, b, _ = cmap(norm(val))
|
|
232
|
+
lum = 0.299*r + 0.587*g + 0.114*b
|
|
233
|
+
color = 'white' if lum < 0.5 else 'black'
|
|
234
|
+
ax.text(j, i + 0.5, f'{val:.2f}', ha='center', va='center',
|
|
235
|
+
fontsize=13, color=color)
|
|
236
|
+
|
|
237
|
+
ax.set_xlim(-0.5, n_cols - 0.5)
|
|
238
|
+
ax.set_xticks(np.arange(n_cols))
|
|
239
|
+
ax.set_xticklabels(metrics, rotation=30, ha='right', fontsize=14)
|
|
240
|
+
ax.tick_params(axis='x', bottom=False, top=False, length=0)
|
|
241
|
+
ax.set_yticks(np.arange(n_rows) + 0.5)
|
|
242
|
+
ax.set_yticklabels(methods, fontsize=14)
|
|
243
|
+
ax.set_frame_on(False)
|
|
244
|
+
ax.invert_yaxis()
|
|
245
|
+
|
|
246
|
+
fig.tight_layout(pad=2)
|
|
247
|
+
os.makedirs('./figures', exist_ok=True)
|
|
248
|
+
fig.savefig('./figures/heatmap.png', dpi=300)
|
|
249
|
+
plt.close(fig)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Related files
|
|
255
|
+
|
|
256
|
+
- [SKILL.md](../SKILL.md) — When to use this skill
|
|
257
|
+
- [api.md](api.md) — Reusable helper implementations
|
|
258
|
+
- [common-patterns.md](common-patterns.md) — Layout and encoding patterns used above
|
|
259
|
+
- [design-theory.md](design-theory.md) — Why these choices exist
|
|
260
|
+
- [chart-types.md](chart-types.md) — Radar, 3D sphere, scatter, fill_between
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PyMuPDF>=1.24.0,<2.0.0
|