@nahisaho/satori 0.1.0
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/LICENCE +0 -0
- package/README.md +191 -0
- package/bin/satori.js +95 -0
- package/package.json +29 -0
- package/src/.github/skills/scientific-academic-writing/SKILL.md +361 -0
- package/src/.github/skills/scientific-academic-writing/assets/acs_article.md +199 -0
- package/src/.github/skills/scientific-academic-writing/assets/elsevier_article.md +244 -0
- package/src/.github/skills/scientific-academic-writing/assets/ieee_transactions.md +212 -0
- package/src/.github/skills/scientific-academic-writing/assets/imrad_standard.md +181 -0
- package/src/.github/skills/scientific-academic-writing/assets/nature_article.md +179 -0
- package/src/.github/skills/scientific-academic-writing/assets/qiita_technical_article.md +385 -0
- package/src/.github/skills/scientific-academic-writing/assets/science_research_article.md +169 -0
- package/src/.github/skills/scientific-bioinformatics/SKILL.md +220 -0
- package/src/.github/skills/scientific-biosignal-processing/SKILL.md +357 -0
- package/src/.github/skills/scientific-causal-inference/SKILL.md +347 -0
- package/src/.github/skills/scientific-cheminformatics/SKILL.md +196 -0
- package/src/.github/skills/scientific-data-preprocessing/SKILL.md +413 -0
- package/src/.github/skills/scientific-data-simulation/SKILL.md +244 -0
- package/src/.github/skills/scientific-doe/SKILL.md +360 -0
- package/src/.github/skills/scientific-eda-correlation/SKILL.md +141 -0
- package/src/.github/skills/scientific-feature-importance/SKILL.md +208 -0
- package/src/.github/skills/scientific-image-analysis/SKILL.md +310 -0
- package/src/.github/skills/scientific-materials-characterization/SKILL.md +368 -0
- package/src/.github/skills/scientific-meta-analysis/SKILL.md +352 -0
- package/src/.github/skills/scientific-metabolomics/SKILL.md +326 -0
- package/src/.github/skills/scientific-ml-classification/SKILL.md +265 -0
- package/src/.github/skills/scientific-ml-regression/SKILL.md +215 -0
- package/src/.github/skills/scientific-multi-omics/SKILL.md +303 -0
- package/src/.github/skills/scientific-network-analysis/SKILL.md +257 -0
- package/src/.github/skills/scientific-pca-tsne/SKILL.md +235 -0
- package/src/.github/skills/scientific-pipeline-scaffold/SKILL.md +331 -0
- package/src/.github/skills/scientific-process-optimization/SKILL.md +215 -0
- package/src/.github/skills/scientific-publication-figures/SKILL.md +208 -0
- package/src/.github/skills/scientific-sequence-analysis/SKILL.md +389 -0
- package/src/.github/skills/scientific-spectral-signal/SKILL.md +227 -0
- package/src/.github/skills/scientific-statistical-testing/SKILL.md +240 -0
- package/src/.github/skills/scientific-survival-clinical/SKILL.md +239 -0
- package/src/.github/skills/scientific-time-series/SKILL.md +291 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scientific-process-optimization
|
|
3
|
+
description: |
|
|
4
|
+
応答曲面法(ML-RSM)とパレート多目的最適化のスキル。プロセスパラメータの最適条件探索、
|
|
5
|
+
コンターマップ、プロセスウィンドウ可視化を行う際に使用。
|
|
6
|
+
Scientific Skills Exp-12, 13 で確立したパターン。
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Scientific Process Optimization (RSM & Pareto)
|
|
10
|
+
|
|
11
|
+
機械学習ベースの応答曲面法(ML-Response Surface Methodology)と
|
|
12
|
+
多目的パレート最適化を用いて、プロセスパラメータの最適条件を探索するスキル。
|
|
13
|
+
半導体プロセス(エッチング、成膜)や材料合成の最適化に適用。
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- プロセスパラメータの最適条件を探索したいとき
|
|
18
|
+
- 2 変数の応答曲面(コンターマップ)を可視化したいとき
|
|
19
|
+
- 複数の目的関数間のトレードオフを分析したいとき
|
|
20
|
+
- パレート最適解(非劣解集合)を求めたいとき
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
## 標準パイプライン
|
|
25
|
+
|
|
26
|
+
### 1. ML ベース応答曲面(コンターマップ)
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
import numpy as np
|
|
30
|
+
import matplotlib.pyplot as plt
|
|
31
|
+
from sklearn.ensemble import GradientBoostingRegressor
|
|
32
|
+
|
|
33
|
+
def response_surface_2d(model, X_train, feature_names,
|
|
34
|
+
var1_name, var2_name, target_name,
|
|
35
|
+
fixed_values=None, resolution=50, figsize=(8, 7)):
|
|
36
|
+
"""
|
|
37
|
+
学習済みモデルを用いて 2 変数の応答曲面を描画する。
|
|
38
|
+
他の変数は中央値(または fixed_values で指定)に固定。
|
|
39
|
+
"""
|
|
40
|
+
var1_idx = list(feature_names).index(var1_name)
|
|
41
|
+
var2_idx = list(feature_names).index(var2_name)
|
|
42
|
+
|
|
43
|
+
# 固定値:中央値をデフォルトに
|
|
44
|
+
if fixed_values is None:
|
|
45
|
+
fixed_values = np.median(X_train, axis=0)
|
|
46
|
+
else:
|
|
47
|
+
fixed_values = np.array(fixed_values)
|
|
48
|
+
|
|
49
|
+
# メッシュグリッド定義
|
|
50
|
+
v1_range = np.linspace(X_train[:, var1_idx].min(),
|
|
51
|
+
X_train[:, var1_idx].max(), resolution)
|
|
52
|
+
v2_range = np.linspace(X_train[:, var2_idx].min(),
|
|
53
|
+
X_train[:, var2_idx].max(), resolution)
|
|
54
|
+
V1, V2 = np.meshgrid(v1_range, v2_range)
|
|
55
|
+
|
|
56
|
+
# 予測用入力を構築
|
|
57
|
+
X_grid = np.tile(fixed_values, (resolution * resolution, 1))
|
|
58
|
+
X_grid[:, var1_idx] = V1.ravel()
|
|
59
|
+
X_grid[:, var2_idx] = V2.ravel()
|
|
60
|
+
|
|
61
|
+
Z = model.predict(X_grid).reshape(V1.shape)
|
|
62
|
+
|
|
63
|
+
# 描画
|
|
64
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
65
|
+
cf = ax.contourf(V1, V2, Z, levels=20, cmap="viridis")
|
|
66
|
+
cs = ax.contour(V1, V2, Z, levels=10, colors="white", linewidths=0.5, alpha=0.5)
|
|
67
|
+
ax.clabel(cs, inline=True, fontsize=8, fmt="%.1f")
|
|
68
|
+
plt.colorbar(cf, ax=ax, label=target_name)
|
|
69
|
+
ax.set_xlabel(var1_name)
|
|
70
|
+
ax.set_ylabel(var2_name)
|
|
71
|
+
ax.set_title(f"Response Surface: {target_name}", fontweight="bold")
|
|
72
|
+
plt.tight_layout()
|
|
73
|
+
plt.savefig(f"figures/response_surface_{var1_name}_{var2_name}.png",
|
|
74
|
+
dpi=300, bbox_inches="tight")
|
|
75
|
+
plt.close()
|
|
76
|
+
return V1, V2, Z
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 2. プロセスウィンドウ可視化
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
def process_window(models, X_train, feature_names,
|
|
83
|
+
var1_name, var2_name, targets_specs,
|
|
84
|
+
resolution=50, figsize=(8, 7)):
|
|
85
|
+
"""
|
|
86
|
+
複数ターゲットの許容範囲を満たすプロセスウィンドウを可視化する。
|
|
87
|
+
targets_specs: [(model, target_name, min_val, max_val), ...]
|
|
88
|
+
"""
|
|
89
|
+
var1_idx = list(feature_names).index(var1_name)
|
|
90
|
+
var2_idx = list(feature_names).index(var2_name)
|
|
91
|
+
fixed = np.median(X_train, axis=0)
|
|
92
|
+
|
|
93
|
+
v1_range = np.linspace(X_train[:, var1_idx].min(),
|
|
94
|
+
X_train[:, var1_idx].max(), resolution)
|
|
95
|
+
v2_range = np.linspace(X_train[:, var2_idx].min(),
|
|
96
|
+
X_train[:, var2_idx].max(), resolution)
|
|
97
|
+
V1, V2 = np.meshgrid(v1_range, v2_range)
|
|
98
|
+
|
|
99
|
+
X_grid = np.tile(fixed, (resolution * resolution, 1))
|
|
100
|
+
X_grid[:, var1_idx] = V1.ravel()
|
|
101
|
+
X_grid[:, var2_idx] = V2.ravel()
|
|
102
|
+
|
|
103
|
+
feasible = np.ones(resolution * resolution, dtype=bool)
|
|
104
|
+
for model, tname, tmin, tmax in targets_specs:
|
|
105
|
+
pred = model.predict(X_grid)
|
|
106
|
+
feasible &= (pred >= tmin) & (pred <= tmax)
|
|
107
|
+
|
|
108
|
+
feasible_map = feasible.reshape(V1.shape).astype(float)
|
|
109
|
+
|
|
110
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
111
|
+
ax.contourf(V1, V2, feasible_map, levels=[0.5, 1.5],
|
|
112
|
+
colors=["#90EE90"], alpha=0.5)
|
|
113
|
+
ax.contour(V1, V2, feasible_map, levels=[0.5], colors=["green"], linewidths=2)
|
|
114
|
+
ax.set_xlabel(var1_name)
|
|
115
|
+
ax.set_ylabel(var2_name)
|
|
116
|
+
ax.set_title("Process Window (Feasible Region)", fontweight="bold")
|
|
117
|
+
plt.tight_layout()
|
|
118
|
+
plt.savefig("figures/process_window.png", dpi=300, bbox_inches="tight")
|
|
119
|
+
plt.close()
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 3. パレート多目的最適化
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
def pareto_optimization(df, obj1_col, obj2_col, obj1_minimize=True,
|
|
126
|
+
obj2_minimize=True, figsize=(8, 7)):
|
|
127
|
+
"""
|
|
128
|
+
2 目的のパレートフロントを抽出して可視化する。
|
|
129
|
+
"""
|
|
130
|
+
points = df[[obj1_col, obj2_col]].values.copy()
|
|
131
|
+
|
|
132
|
+
# 最小化形式に統一
|
|
133
|
+
if not obj1_minimize:
|
|
134
|
+
points[:, 0] = -points[:, 0]
|
|
135
|
+
if not obj2_minimize:
|
|
136
|
+
points[:, 1] = -points[:, 1]
|
|
137
|
+
|
|
138
|
+
# パレート非劣解の抽出
|
|
139
|
+
is_pareto = np.ones(len(points), dtype=bool)
|
|
140
|
+
for i in range(len(points)):
|
|
141
|
+
if is_pareto[i]:
|
|
142
|
+
is_pareto[i] = True
|
|
143
|
+
for j in range(len(points)):
|
|
144
|
+
if i != j and is_pareto[j]:
|
|
145
|
+
if np.all(points[j] <= points[i]) and np.any(points[j] < points[i]):
|
|
146
|
+
is_pareto[i] = False
|
|
147
|
+
break
|
|
148
|
+
|
|
149
|
+
pareto_df = df[is_pareto].copy()
|
|
150
|
+
pareto_df = pareto_df.sort_values(obj1_col)
|
|
151
|
+
pareto_df.to_csv("results/pareto_optimal.csv", index=False)
|
|
152
|
+
|
|
153
|
+
# 描画
|
|
154
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
155
|
+
ax.scatter(df[obj1_col], df[obj2_col], alpha=0.3, s=20,
|
|
156
|
+
color="gray", label="All solutions")
|
|
157
|
+
ax.scatter(pareto_df[obj1_col], pareto_df[obj2_col],
|
|
158
|
+
color="red", s=80, zorder=5, edgecolors="black",
|
|
159
|
+
linewidth=1, label=f"Pareto front (n={len(pareto_df)})")
|
|
160
|
+
ax.plot(pareto_df[obj1_col], pareto_df[obj2_col],
|
|
161
|
+
"r--", linewidth=1.5, alpha=0.7)
|
|
162
|
+
|
|
163
|
+
ax.set_xlabel(obj1_col)
|
|
164
|
+
ax.set_ylabel(obj2_col)
|
|
165
|
+
ax.set_title("Pareto Front", fontweight="bold")
|
|
166
|
+
ax.legend()
|
|
167
|
+
plt.tight_layout()
|
|
168
|
+
plt.savefig("figures/pareto_front.png", dpi=300, bbox_inches="tight")
|
|
169
|
+
plt.close()
|
|
170
|
+
|
|
171
|
+
return pareto_df
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 4. グリッドサーチによる最適条件探索
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
def grid_search_optimum(model, feature_names, bounds,
|
|
178
|
+
target_name, maximize=True, n_points=10000):
|
|
179
|
+
"""
|
|
180
|
+
ランダムグリッドサーチで最適条件を探索する。
|
|
181
|
+
bounds: {feature_name: (min, max)} の辞書
|
|
182
|
+
"""
|
|
183
|
+
rng = np.random.default_rng(42)
|
|
184
|
+
X_search = np.column_stack([
|
|
185
|
+
rng.uniform(bounds[f][0], bounds[f][1], n_points)
|
|
186
|
+
if f in bounds
|
|
187
|
+
else np.full(n_points, bounds.get(f, (0, 0))[0])
|
|
188
|
+
for f in feature_names
|
|
189
|
+
])
|
|
190
|
+
|
|
191
|
+
predictions = model.predict(X_search)
|
|
192
|
+
best_idx = np.argmax(predictions) if maximize else np.argmin(predictions)
|
|
193
|
+
|
|
194
|
+
optimal_conditions = {f: X_search[best_idx, i]
|
|
195
|
+
for i, f in enumerate(feature_names)}
|
|
196
|
+
optimal_conditions[f"predicted_{target_name}"] = predictions[best_idx]
|
|
197
|
+
|
|
198
|
+
return optimal_conditions
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## References
|
|
202
|
+
|
|
203
|
+
### Output Files
|
|
204
|
+
|
|
205
|
+
| ファイル | 形式 |
|
|
206
|
+
|---|---|
|
|
207
|
+
| `results/pareto_optimal.csv` | CSV |
|
|
208
|
+
| `figures/response_surface_*.png` | PNG |
|
|
209
|
+
| `figures/process_window.png` | PNG |
|
|
210
|
+
| `figures/pareto_front.png` | PNG |
|
|
211
|
+
|
|
212
|
+
#### 参照実験
|
|
213
|
+
|
|
214
|
+
- **Exp-12**: エッチング速度 vs 選択比のパレート最適化、ML-RSM
|
|
215
|
+
- **Exp-13**: TCO 膜の粗さ vs 透過率パレート最適化、成膜条件 RSM
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scientific-publication-figures
|
|
3
|
+
description: |
|
|
4
|
+
論文品質(Nature/Science/Cell レベル)の科学図表を作成するスキル。matplotlib rcParams 設定、
|
|
5
|
+
DPI 300、spines 制御、カラーパレット選択、マルチパネル構成を行う際に使用。
|
|
6
|
+
Scientific Skills Exp-10 で確立し、Exp-11〜13 で継承したパターン。
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Scientific Publication-Quality Figure Generation
|
|
10
|
+
|
|
11
|
+
Nature/Science/Cell 掲載レベルの科学図表を matplotlib/seaborn で作成するスキル。
|
|
12
|
+
Exp-10 で確立した 15 種の図表テンプレートと、全実験に共通するスタイル設定を提供する。
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- 論文投稿用の高品質図表を作成するとき
|
|
17
|
+
- 複数パネルの composite figure を構成するとき
|
|
18
|
+
- DPI 300 以上、適切なフォントサイズ・カラーパレットが必要なとき
|
|
19
|
+
- 図表がジャーナルのスタイルガイドに準拠する必要があるとき
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
## グローバルスタイル設定
|
|
24
|
+
|
|
25
|
+
以下の設定をスクリプトの冒頭で必ず適用する。
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
import matplotlib.pyplot as plt
|
|
29
|
+
import matplotlib as mpl
|
|
30
|
+
|
|
31
|
+
def setup_publication_style():
|
|
32
|
+
"""Nature/Science 品質の matplotlib rcParams を設定する。"""
|
|
33
|
+
plt.rcParams.update({
|
|
34
|
+
# フォント
|
|
35
|
+
"font.family": "sans-serif",
|
|
36
|
+
"font.sans-serif": ["Arial", "Helvetica", "DejaVu Sans"],
|
|
37
|
+
"font.size": 10,
|
|
38
|
+
"axes.titlesize": 12,
|
|
39
|
+
"axes.labelsize": 11,
|
|
40
|
+
"xtick.labelsize": 9,
|
|
41
|
+
"ytick.labelsize": 9,
|
|
42
|
+
"legend.fontsize": 9,
|
|
43
|
+
|
|
44
|
+
# 線・マーカー
|
|
45
|
+
"axes.linewidth": 1.2,
|
|
46
|
+
"lines.linewidth": 1.5,
|
|
47
|
+
"lines.markersize": 6,
|
|
48
|
+
|
|
49
|
+
# スパイン
|
|
50
|
+
"axes.spines.top": False,
|
|
51
|
+
"axes.spines.right": False,
|
|
52
|
+
|
|
53
|
+
# グリッド
|
|
54
|
+
"axes.grid": False,
|
|
55
|
+
|
|
56
|
+
# 保存設定
|
|
57
|
+
"savefig.dpi": 300,
|
|
58
|
+
"savefig.bbox": "tight",
|
|
59
|
+
"savefig.transparent": False,
|
|
60
|
+
|
|
61
|
+
# Figure 背景
|
|
62
|
+
"figure.facecolor": "white",
|
|
63
|
+
"axes.facecolor": "white",
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## カラーパレット
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
# Nature-inspired パレット(Exp-10)
|
|
71
|
+
NATURE_PALETTE = [
|
|
72
|
+
"#E64B35", # 赤
|
|
73
|
+
"#4DBBD5", # 水色
|
|
74
|
+
"#00A087", # 緑
|
|
75
|
+
"#3C5488", # 紺
|
|
76
|
+
"#F39B7F", # サーモン
|
|
77
|
+
"#8491B4", # グレー青
|
|
78
|
+
"#91D1C2", # ミント
|
|
79
|
+
"#DC9C6D", # オレンジ
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
# 材料・群カテゴリ用
|
|
83
|
+
MATERIAL_PALETTE = {
|
|
84
|
+
"Set2": "seaborn Set2(最大 8 色、差別化しやすい)",
|
|
85
|
+
"tab10": "matplotlib tab10(最大 10 色)",
|
|
86
|
+
"Paired": "seaborn Paired(最大 12 色、対比較向き)",
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# 連続値用
|
|
90
|
+
CONTINUOUS_CMAPS = {
|
|
91
|
+
"viridis": "知覚均一(デフォルト推奨)",
|
|
92
|
+
"RdBu_r": "相関ヒートマップ(中心=0)",
|
|
93
|
+
"YlOrRd": "単方向の強度(密度、温度)",
|
|
94
|
+
"coolwarm": "二方向(応力の引張 vs 圧縮)",
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 共通保存関数
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
def save_fig(fig, filename, dpi=300, formats=("png",)):
|
|
102
|
+
"""図を指定された形式で保存する。"""
|
|
103
|
+
for fmt in formats:
|
|
104
|
+
filepath = f"figures/{filename}.{fmt}"
|
|
105
|
+
fig.savefig(filepath, dpi=dpi, bbox_inches="tight",
|
|
106
|
+
facecolor="white", edgecolor="none")
|
|
107
|
+
plt.close(fig)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 主要図表テンプレート
|
|
111
|
+
|
|
112
|
+
### 1. Violin + Strip Plot(有意差付き)
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
import seaborn as sns
|
|
116
|
+
from scipy import stats
|
|
117
|
+
|
|
118
|
+
def plot_violin_with_significance(df, x, y, pairs=None, figsize=(10, 6)):
|
|
119
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
120
|
+
sns.violinplot(data=df, x=x, y=y, palette=NATURE_PALETTE,
|
|
121
|
+
inner=None, alpha=0.3, ax=ax)
|
|
122
|
+
sns.stripplot(data=df, x=x, y=y, palette=NATURE_PALETTE,
|
|
123
|
+
size=3, alpha=0.5, ax=ax)
|
|
124
|
+
|
|
125
|
+
# 有意差ブラケット(pairs 指定時)
|
|
126
|
+
if pairs:
|
|
127
|
+
y_max = df[y].max()
|
|
128
|
+
for i, (g1, g2) in enumerate(pairs):
|
|
129
|
+
d1 = df[df[x] == g1][y]
|
|
130
|
+
d2 = df[df[x] == g2][y]
|
|
131
|
+
stat, pval = stats.mannwhitneyu(d1, d2)
|
|
132
|
+
stars = "***" if pval < 0.001 else "**" if pval < 0.01 else "*" if pval < 0.05 else "ns"
|
|
133
|
+
h = y_max * (1.05 + i * 0.08)
|
|
134
|
+
# ブラケット描画は adjustText か手動 annotate
|
|
135
|
+
ax.text((list(df[x].unique()).index(g1) +
|
|
136
|
+
list(df[x].unique()).index(g2)) / 2,
|
|
137
|
+
h, stars, ha="center", fontsize=12, fontweight="bold")
|
|
138
|
+
save_fig(fig, f"violin_{y}")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 2. Forest Plot(メタ分析風)
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
def plot_forest(effects, ci_lower, ci_upper, labels, figsize=(10, 8)):
|
|
145
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
146
|
+
y_pos = range(len(labels))
|
|
147
|
+
ax.errorbar(effects, y_pos, xerr=[np.array(effects) - np.array(ci_lower),
|
|
148
|
+
np.array(ci_upper) - np.array(effects)],
|
|
149
|
+
fmt="D", color=NATURE_PALETTE[0], markersize=8,
|
|
150
|
+
capsize=4, linewidth=2)
|
|
151
|
+
ax.axvline(0, color="gray", linestyle="--", linewidth=1)
|
|
152
|
+
ax.set_yticks(y_pos)
|
|
153
|
+
ax.set_yticklabels(labels)
|
|
154
|
+
ax.set_xlabel("Effect Size")
|
|
155
|
+
ax.set_title("Forest Plot", fontweight="bold")
|
|
156
|
+
save_fig(fig, "forest_plot")
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 3. マルチパネル Composite Figure
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
import matplotlib.gridspec as gridspec
|
|
163
|
+
|
|
164
|
+
def create_composite_figure(plot_functions, layout=(2, 3),
|
|
165
|
+
figsize=(18, 12), panel_labels=True):
|
|
166
|
+
"""
|
|
167
|
+
複数の描画関数を composite figure にまとめる。
|
|
168
|
+
plot_functions: [(func, kwargs), ...] のリスト
|
|
169
|
+
"""
|
|
170
|
+
fig = plt.figure(figsize=figsize)
|
|
171
|
+
gs = gridspec.GridSpec(*layout, figure=fig, hspace=0.35, wspace=0.3)
|
|
172
|
+
|
|
173
|
+
for i, (func, kwargs) in enumerate(plot_functions):
|
|
174
|
+
row, col = divmod(i, layout[1])
|
|
175
|
+
ax = fig.add_subplot(gs[row, col])
|
|
176
|
+
func(ax=ax, **kwargs)
|
|
177
|
+
|
|
178
|
+
if panel_labels:
|
|
179
|
+
ax.text(-0.1, 1.1, chr(65 + i), # A, B, C, ...
|
|
180
|
+
transform=ax.transAxes, fontsize=16,
|
|
181
|
+
fontweight="bold", va="top")
|
|
182
|
+
|
|
183
|
+
save_fig(fig, "composite_figure")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 図のサイズガイドライン
|
|
187
|
+
|
|
188
|
+
| 用途 | サイズ (inches) | 備考 |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| 1 カラム | (3.5, 3.0) | Nature 1 カラム幅 ≈ 89 mm |
|
|
191
|
+
| 1.5 カラム | (5.5, 4.0) | 中間サイズ |
|
|
192
|
+
| 2 カラム | (7.0, 5.0) | Nature 2 カラム幅 ≈ 183 mm |
|
|
193
|
+
| フルページ | (7.0, 9.0) | A4 の余白を除いた高さ |
|
|
194
|
+
|
|
195
|
+
## References
|
|
196
|
+
|
|
197
|
+
### Output Files
|
|
198
|
+
|
|
199
|
+
| ファイル | 形式 |
|
|
200
|
+
|---|---|
|
|
201
|
+
| `figures/*.png` | PNG (300 DPI) |
|
|
202
|
+
| `figures/*.svg` | SVG(ベクター、投稿用) |
|
|
203
|
+
| `figures/*.pdf` | PDF(ベクター、LaTeX 用) |
|
|
204
|
+
|
|
205
|
+
#### 参照実験
|
|
206
|
+
|
|
207
|
+
- **Exp-10**: 15 種の図表テンプレートの完全セット
|
|
208
|
+
- **Exp-11〜13**: rcParams 設定とカラーパレットの継承
|