Skill: Visualization
Use this skill whenever the user asks to:
- Plot, visualize, chart, or graph data.
- Create figures for EDA, reports, dashboards, or presentations.
- Modify or improve existing matplotlib / seaborn code.
- Save figures to disk for reports or notebooks.
Library
- Use matplotlib for charts.
- Use seaborn alongside matplotlib for theming, palettes, and statistical plots.
Global Setup (do this first)
At the start of any notebook or script that produces figures, set the theme once. font_scale enlarges all text elements proportionally, so individual fontsize= arguments are usually unnecessary.
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(
style="whitegrid",
palette="muted",
font_scale=1.2,
)
Japanese text
If any text (titles, labels, legends, annotations) contains Japanese, configure a CJK-capable font, otherwise characters render as tofu (□□□).
Preferred approach (cross-platform):
import japanize_matplotlib # uv add japanize-matplotlib
Alternative (set an installed CJK font explicitly):
plt.rcParams["font.family"] = "Noto Sans CJK JP" # or "IPAexGothic", "Hiragino Sans", "Yu Gothic"
Figure Creation
- Do not use the stateful
plt.figure(...) / plt.plot(...) style.
- Always create figures and axes explicitly, and prefer
constrained_layout=True over tight_layout():
fig, ax = plt.subplots(figsize=(10, 6), constrained_layout=True)
- Use the object-oriented API:
ax.set_title(), ax.set_xlabel(), ax.plot(), etc.
figsize=(10, 6) is a reasonable default. Adjust to content: wide time series → (12, 4), square scatter → (6, 6), multi-panel → scale up accordingly.
Color Map / Color Palette
Choose by data type:
- Categorical:
"muted", "Set2", "colorblind" (seaborn palettes).
- Sequential (continuous):
"viridis", "cividis", "mako" — perceptually uniform.
- Diverging:
"coolwarm", "RdBu", "vlag".
- Forbidden:
"jet", "rainbow" — not perceptually uniform, poor for colorblind viewers.
Font Size
sns.set_theme(font_scale=1.2) covers most cases. Override per-element only when needed (e.g. a long title needs to be smaller, or one label needs emphasis):
ax.set_title("...", fontsize=18)
Do not repeat fontsize= on every call — it is redundant when font_scale is set.
Axis Scale Guidelines
- Bar charts: start y-axis at 0 (
ax.set_ylim(bottom=0)). Truncated bars are misleading.
- Line / scatter: do not force y-axis to 0 — it can hide meaningful variation. Let matplotlib autoscale, or set limits based on the data range.
- Log scale: use
ax.set_yscale("log") when data spans multiple orders of magnitude.
Legend
- Use
ax.legend() only when ≥2 series are plotted.
- If the auto-placement overlaps data, set explicitly:
ax.legend(loc="upper left") or place outside: ax.legend(loc="center left", bbox_to_anchor=(1.0, 0.5)).
Saving
- Save final figures under
outputs/figures/.
- Use the path utilities from
src/analysis_project/paths.py.
from analysis_project.paths import outputs_dir, ensure_parent_dir
# 出力パスを構成して保存
output_path = outputs_dir() / "figures" / "survival_by_class.png"
ensure_parent_dir(output_path)
fig.savefig(output_path, dpi=150)
- Use descriptive snake_case filenames:
monthly_sales_2024h1.png, not fig1.png.
- DPI guidance:
- Notebook / README / slides:
dpi=150
- Publication / print:
dpi=300
- Always call
plt.close(fig) after saving to free memory.
fig.savefig("outputs/figures/monthly_sales.png", dpi=150, bbox_inches="tight")
plt.close(fig)
Chart Quality Checklist
Before finalizing a chart, verify:
Example
from pathlib import Path
import matplotlib.pyplot as plt
import seaborn as sns
import japanize_matplotlib # noqa: F401 # 日本語フォント有効化
sns.set_theme(style="whitegrid", palette="muted", font_scale=1.2)
Path("outputs/figures").mkdir(parents=True, exist_ok=True)
fig, ax = plt.subplots(figsize=(10, 6), constrained_layout=True)
ax.bar(categories, values)
ax.set_title("月別売上推移 (2024年1月〜6月)")
ax.set_xlabel("月")
ax.set_ylabel("売上 (万円)")
ax.set_ylim(bottom=0) # 棒グラフは0起点
fig.savefig("outputs/figures/monthly_sales_2024h1.png", dpi=150, bbox_inches="tight")
plt.close(fig)
1---2name: visualization-23description: Use this when creating, modifying, reviewing, or saving charts, figures, plots, or visual summaries — including matplotlib/seaborn code, EDA figures, report figures, dashboards, or any task involving Japanese chart labels, color palettes, or figure styling.4---56# Skill: Visualization78Use this skill whenever the user asks to:910- Plot, visualize, chart, or graph data.11- Create figures for EDA, reports, dashboards, or presentations.12- Modify or improve existing matplotlib / seaborn code.13- Save figures to disk for reports or notebooks.1415## Library1617- Use **matplotlib** for charts.18- Use **seaborn** alongside matplotlib for theming, palettes, and statistical plots.1920## Global Setup (do this first)2122At the start of any notebook or script that produces figures, set the theme once. `font_scale` enlarges all text elements proportionally, so individual `fontsize=` arguments are usually unnecessary.2324```python25import matplotlib.pyplot as plt26import seaborn as sns2728sns.set_theme(29 style="whitegrid",30 palette="muted",31 font_scale=1.2,32)33```3435### Japanese text3637If any text (titles, labels, legends, annotations) contains Japanese, configure a CJK-capable font, **otherwise characters render as tofu (□□□)**.3839Preferred approach (cross-platform):4041```python42import japanize_matplotlib # uv add japanize-matplotlib43```4445Alternative (set an installed CJK font explicitly):4647```python48plt.rcParams["font.family"] = "Noto Sans CJK JP" # or "IPAexGothic", "Hiragino Sans", "Yu Gothic"49```5051## Figure Creation5253- **Do not** use the stateful `plt.figure(...)` / `plt.plot(...)` style.54- **Always** create figures and axes explicitly, and prefer `constrained_layout=True` over `tight_layout()`:5556```python57fig, ax = plt.subplots(figsize=(10, 6), constrained_layout=True)58```5960- Use the **object-oriented** API: `ax.set_title()`, `ax.set_xlabel()`, `ax.plot()`, etc.61- `figsize=(10, 6)` is a reasonable default. Adjust to content: wide time series → `(12, 4)`, square scatter → `(6, 6)`, multi-panel → scale up accordingly.6263## Color Map / Color Palette6465Choose by data type:6667- **Categorical**: `"muted"`, `"Set2"`, `"colorblind"` (seaborn palettes).68- **Sequential (continuous)**: `"viridis"`, `"cividis"`, `"mako"` — perceptually uniform.69- **Diverging**: `"coolwarm"`, `"RdBu"`, `"vlag"`.70- **Forbidden**: `"jet"`, `"rainbow"` — not perceptually uniform, poor for colorblind viewers.7172## Font Size7374`sns.set_theme(font_scale=1.2)` covers most cases. Override per-element **only when needed** (e.g. a long title needs to be smaller, or one label needs emphasis):7576```python77ax.set_title("...", fontsize=18)78```7980Do **not** repeat `fontsize=` on every call — it is redundant when `font_scale` is set.8182## Axis Scale Guidelines8384- **Bar charts**: start y-axis at 0 (`ax.set_ylim(bottom=0)`). Truncated bars are misleading.85- **Line / scatter**: do **not** force y-axis to 0 — it can hide meaningful variation. Let matplotlib autoscale, or set limits based on the data range.86- **Log scale**: use `ax.set_yscale("log")` when data spans multiple orders of magnitude.8788## Legend8990- Use `ax.legend()` only when ≥2 series are plotted.91- If the auto-placement overlaps data, set explicitly: `ax.legend(loc="upper left")` or place outside: `ax.legend(loc="center left", bbox_to_anchor=(1.0, 0.5))`.9293## Saving9495- Save final figures under `outputs/figures/`.96- Use the path utilities from `src/analysis_project/paths.py`.9798```python99from analysis_project.paths import outputs_dir, ensure_parent_dir100101# 出力パスを構成して保存102output_path = outputs_dir() / "figures" / "survival_by_class.png"103ensure_parent_dir(output_path)104fig.savefig(output_path, dpi=150)105```106107- Use descriptive snake_case filenames: `monthly_sales_2024h1.png`, not `fig1.png`.108- DPI guidance:109 - Notebook / README / slides: `dpi=150`110 - Publication / print: `dpi=300`111- Always call `plt.close(fig)` after saving to free memory.112113```python114fig.savefig("outputs/figures/monthly_sales.png", dpi=150, bbox_inches="tight")115plt.close(fig)116```117118## Chart Quality Checklist119120Before finalizing a chart, verify:121122- [ ] **Title** clearly describes what the chart shows.123- [ ] **Axis labels** include units where applicable (e.g. "売上 (万円)", "Latency (ms)").124- [ ] **Font sizes** are readable (rely on `font_scale=1.2` as baseline).125- [ ] **Color palette** is perceptually uniform / colorblind-friendly (no jet/rainbow).126- [ ] **Date range** noted in title, subtitle, or annotation when relevant.127- [ ] **Sample / filter note** when data is subsetted (e.g. "n=1,234, 2024年1月〜6月").128- [ ] **Bar charts** start y-axis at 0; other chart types use sensible limits.129- [ ] **Legend** present when multiple series; placement does not overlap data.130- [ ] **Japanese text** renders correctly (japanize-matplotlib or CJK font configured).131- [ ] **Saved** to `outputs/figures/` with descriptive filename, followed by `plt.close(fig)`.132133## Example134135```python136from pathlib import Path137import matplotlib.pyplot as plt138import seaborn as sns139import japanize_matplotlib # noqa: F401 # 日本語フォント有効化140141sns.set_theme(style="whitegrid", palette="muted", font_scale=1.2)142143Path("outputs/figures").mkdir(parents=True, exist_ok=True)144145fig, ax = plt.subplots(figsize=(10, 6), constrained_layout=True)146147ax.bar(categories, values)148ax.set_title("月別売上推移 (2024年1月〜6月)")149ax.set_xlabel("月")150ax.set_ylabel("売上 (万円)")151ax.set_ylim(bottom=0) # 棒グラフは0起点152153fig.savefig("outputs/figures/monthly_sales_2024h1.png", dpi=150, bbox_inches="tight")154plt.close(fig)155```