Chọn đúng biểu đồ, kể chuyện với số liệu, và tránh误导 — dựa trên nguyên tắc từ Kieran Healy (Data Visualization, Princeton 2019) và taxonomy từ AntV chart-visualization-skills. Dùng khi cần quyết định loại chart, trình bày insight cho stakeholder, hoặc kiểm tra xem figure có gây hiểu lầm không. Để vẽ Python thực tế, chuyển sang matplotlib / seaborn / scientific-visualization.
Scanned 5/27/2026
Install via CLI
openskills install charlieviettq/awesome-agent-skill---
name: data-viz-storytelling-healy
description: >
Chọn đúng biểu đồ, kể chuyện với số liệu, và tránh误导 — dựa trên nguyên tắc
từ Kieran Healy (Data Visualization, Princeton 2019) và taxonomy từ AntV
chart-visualization-skills. Dùng khi cần quyết định loại chart, trình bày insight
cho stakeholder, hoặc kiểm tra xem figure có gây hiểu lầm không. Để vẽ Python
thực tế, chuyển sang matplotlib / seaborn / scientific-visualization.
metadata:
skill-author: community
sources:
- name: "Kieran Healy, Data Visualization: A Practical Introduction (Princeton, 2019)"
url: https://press.princeton.edu/books/ebook/9780691185064/data-visualization-pdf
- name: "AntV chart-visualization-skills (MIT)"
url: https://github.com/antvis/chart-visualization-skills
---
# Data Visualization & Storytelling (Healy + AntV)
> "The tools you use can help you live up to the right standards.
> But they cannot make you do the right thing."
> — Kieran Healy, *Data Visualization*, Ch. 1
## When to Use This Skill
- Deciding **which chart type** fits the analytical question
- Writing a report or slide deck where **numbers need a narrative**
- Reviewing a figure for **honesty / misleading patterns**
- Drafting an insight summary with **claim → evidence → caveat** structure
- Choosing between infographic (visual design) and statistical figure (accuracy)
**For actual plotting code** → use `matplotlib`, `seaborn`, or `scientific-visualization`.
---
## Section 1 — Honesty & Judgment (Healy Ch. 1)
Before choosing colors or chart types, verify the figure does not mislead.
### 1.1 Pre-plot Honesty Checklist
| Check | Why it matters |
|-------|----------------|
| Baseline / zero start | Bar charts starting above zero exaggerate differences. Line charts may omit zero legitimately if the focus is trend, not level. |
| Dual axes | Two Y-axes on one plot invite false correlation. Prefer faceted panels or indexed series. |
| Cherry-picked window | Short time windows can hide long-term patterns. Always show context. |
| Aggregation level | Averages can hide distribution shape. Consider showing raw data, box plots, or density. |
| Proportional vs absolute | Normalize when comparing groups of different size; keep raw counts available. |
| Color encoding | Do not use rainbow/palette that implies order for categorical data. Use colorblind-safe palettes. |
| Uncertainty | Show CI, prediction bands, or error bars when presenting estimates. |
| Axis labels & units | Every axis must state what it measures and in what unit. |
**Rule of thumb:** If removing context (time range, N, CI) changes the takeaway, the figure is misleading as-is.
### 1.2 Perception Principles (Healy Ch. 1 + Cleveland)
Humans perceive some encodings more accurately than others:
1. **Position on common scale** — most accurate (scatter, line)
2. **Position on different scale** — good (grouped bar, faceted)
3. **Length / direction** — moderate
4. **Angle / area** — poor (avoid pie charts for comparison)
5. **Color intensity / shape** — worst for magnitude; OK for categories
**Implication:** Prefer dot plots or bar charts over pie/bubble for quantitative comparison.
---
## Section 2 — Chart Selection Rubric (AntV taxonomy → Python)
Ask: **"What is the analytical question?"** then pick the chart family.
| Question family | Chart types | Python (seaborn/matplotlib) |
|-----------------|-------------|-----------------------------|
| **Trend over time** | Line, area, step | `sns.lineplot`, `ax.plot`, `ax.fill_between` |
| **Comparison (categories)** | Bar (grouped/stacked), lollipop | `sns.barplot`, `ax.barh` |
| **Part-to-whole** | Stacked bar, waffle, pie (sparingly) | `ax.bar(stacked)`, avoid pie for >3 slices |
| **Distribution** | Histogram, KDE, box, violin, ridgeline | `sns.histplot`, `sns.kdeplot`, `sns.boxplot`, `sns.violinplot` |
| **Relationship (2+ vars)** | Scatter, bubble, hexbin, 2D density | `sns.scatterplot`, `ax.hexbin`, `sns.jointplot` |
| **Ranking** | Lollipop, horizontal bar (sorted) | `ax.barh` (sorted) |
| **Deviation / contrast** | Diverging bar, slope chart, dumbbell | Custom `ax.barh` with center baseline |
| **Geography** | Choropleth, bubble map | `geopandas` + matplotlib; or Folium |
| **Hierarchy / flow** | Treemap, sankey, dendrogram | `squarify`, `matplotlib-sankey` |
| **Multi-variate summary** | Parallel coordinates, radar, heatmap | `pd.plotting.parallel_coordinates`, `sns.heatmap` |
| **Model diagnostics** | Residual plot, calibration curve, lift/gains | `sns.residplot`, custom calibration, KS plot |
### Decision Flow
```
1. How many variables? → 1 (distribution) | 2 (relationship) | 3+ (multivariate)
2. Is there a time component? → Yes: line/area trend
3. Am I comparing groups? → Yes: bar/lollipop
4. Am I showing composition? → Yes: stacked bar > pie
5. Am I showing uncertainty? → Always add CI/bands
6. Audience? → Expert: detail plot | Executive: annotated summary + callout
```
---
## Section 3 — Building Plots Layer by Layer (Healy Ch. 3)
Healy teaches the **grammar of graphics**: data → mapping → geom → stat → coord → facet → theme.
Mapped to matplotlib/seaborn:
| Grammar layer | ggplot concept | matplotlib / seaborn equivalent |
|---------------|----------------|--------------------------------|
| Data | `ggplot(df)` | Pass DataFrame to seaborn or plot columns |
| Aesthetic mapping | `aes(x=, y=, color=)` | `x=`, `y=`, `hue=` params in seaborn; manual in matplotlib |
| Geometry | `geom_point`, `geom_line` | `ax.scatter`, `ax.plot`, `sns.scatterplot` |
| Statistical transform | `stat_summary`, `geom_smooth` | `sns.regplot`, `sns.aggplot`-like via groupby + plot |
| Coordinate system | `coord_flip`, `coord_polar` | `ax.invert_yaxis()`, projection='polar' |
| Facet | `facet_wrap(~var)` | `sns.FacetGrid` / `sns.relplot(col=)` |
| Theme / labels | `labs()`, `theme_minimal()` | `ax.set_title/labels`, spine removal, style sheets |
**Workflow in Python:**
```python
import seaborn as sns
import matplotlib.pyplot as plt
# Layer 1: data + mapping + geom
g = sns.relplot(
data=df,
x="feature_date", y="default_rate",
hue="segment", col="product",
kind="line", facet_kws={"sharey": False}
)
# Layer 2: annotation
g.fig.suptitle("Default Rate Trend by Segment & Product", y=1.02)
g.set_axis_labels("Month", "Default Rate (%)")
# Layer 3: refine
g.tick_params(axis="x", rotation=45)
sns.despine()
plt.tight_layout()
```
---
## Section 4 — Narrative with Numbers (AntV T8 + Report Pattern)
When writing a data-driven section (report, slide, notebook conclusion), follow:
### 4.1 Claim-Evidence-Caveat Pattern
```
**Claim:** "Approval rate for Segment A dropped 15 pp in Q3."
**Evidence:**
- Figure: Line chart of monthly approval rate, Segments A/B/C, Jan–Sep
- Table: N, mean, CI per segment per quarter
**Caveat:**
- "Data window excludes Jan policy change; Segment C sample < 500."
```
### 4.2 Entity Annotation (T8-inspired)
In markdown, annotate key entities so readers (and agents) can parse them:
```markdown
The [metric:approval_rate] for [dimension:Segment_A] was [value:72%] ([trend:down_15pp])
in [dimension:Q3_2026], compared to [value:87%] in [dimension:Q2_2026].
```
This mirrors AntV T8's entity-based narrative but works in plain markdown.
### 4.3 Figure Caption Template (Healy Ch. 5)
A good caption has:
1. **What** is being shown (chart type + variables)
2. **Who/when** (cohort, time window, N)
3. **Key takeaway** (one sentence)
4. **Caveat** (if any)
Example:
> Figure 3. Monthly default rate (%) by risk tier, Jan 2025 – Sep 2026 (N = 142,000). Tier D shows the steepest increase after the Q2 policy change. 95% CI shown in shading.
---
## Section 5 — Model → Visualization (Healy Ch. 6, Credit Scoring context)
Common model diagnostic plots for credit scoring:
| Diagnostic | Chart | Purpose |
|------------|-------|---------|
| Residual analysis | Residual vs predicted, Q-Q plot | Check model assumptions |
| Feature effect | Partial dependence / ICE | Direction & magnitude of top features |
| Discrimination | KS plot, ROC curve, PR curve | Rank-ordering ability |
| Calibration | Calibration curve (predicted vs actual) | Score reliability |
| Stability | PSI over time, population distribution shift | Feature / score drift |
| Segmentation | Slice metrics (Gini by segment, approval rate by tier) | Fairness & performance parity |
| SHAP | Beeswarm, waterfall, scatter | Explainability (see `shap` skill) |
---
## Section 6 — Refinement Quick Reference
For detailed publication styling → `scientific-visualization`.
| Aspect | Guideline |
|--------|-----------|
| Color palette | Use colorblind-safe (viridis, Okabe-Ito). Avoid rainbow for sequential data. |
| Grayscale test | Figure should still be readable in black & white. |
| Font size | Minimum 6 pt at final print size; larger for presentations. |
| Spines | Remove top & right spines for cleaner look. |
| Grid lines | Use light, sparse gridlines; avoid heavy grid. |
| Legends | Place near data; consider direct labels instead. |
| Aspect ratio | Choose so perception is not distorted (banking to 45° for trends). |
| File format | PDF/SVG for vector; PNG at 300+ DPI for raster. |
---
## Section 7 — Infographic vs Statistical Figure
| Dimension | Infographic (`infographics` skill) | Statistical Figure (this + `scientific-visualization`) |
|-----------|------------------------------------|--------------------------------------------------------|
| Primary goal | Communicate key message visually | Show data accurately & completely |
| Audience | General / executive / marketing | Analysts, reviewers, risk committee |
| Data density | Low-moderate (curated highlights) | High (full distribution, uncertainty) |
| Aesthetics | Template-driven, branded | Clean, minimal chart junk |
| Tool | Nano Banana Pro / design tools | matplotlib / seaborn / plotly |
**Choose infographic when:** one key message, non-technical audience, visual impact matters.
**Choose statistical figure when:** accuracy, reproducibility, peer review required.
---
## References
- Healy, K. (2019). *Data Visualization: A Practical Introduction*. Princeton University Press.
- AntV chart-visualization-skills: https://github.com/antvis/chart-visualization-skills (MIT)
- Cleveland, W. S. & McGill, R. (1984). "Graphical Perception: Theory, Experimentation, and Application to the Development of Graphical Methods." *JASA*.
- Tufte, E. R. (2001). *The Visual Display of Quantitative Information*. Graphics Press.
No comments yet. Be the first to comment!