beautiful-data-viz — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited beautiful-data-viz (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The pack's shared rules for any data visual, whatever the library or medium. Show the data, remove decoration, label directly, and add only the context the reader needs. Other skills that draw figures (/plotly-dashboard-skill, /notebooks, the bio-* reporting skills) follow these rules and add only what their medium needs.
Use colorblind-safe colors, never make color the only encoding (add position, shape, line style, or a direct label), and keep the figure readable in greyscale print. When color is warranted, pick it from references/palettes.md.
set_beautiful_style(...) from assets/beautiful_style.py. It sets a grey series cycle with distinct line styles and returns a config whose accent is a colorblind-safe highlight color for the current background.theme_classic() or theme_minimal(), scale_colour_grey() for neutral series, and scale_colour_manual() to give only the finding the accent.colorway and the accent added per trace; see /plotly-dashboard-skill references/style.md.Image.open(path).convert("L") with Pillow).pixi.toml (this skill ships one in pixi.toml), or a PEP 723 script run with uv run --script, as in scripts/export_fixture.py.| Task | Action |
|---|---|
| Apply matplotlib style | cfg = set_beautiful_style(medium="paper") from assets/beautiful_style.py |
| Highlight the finding | ax.plot(x, y, color=cfg.accent); all other series keep the grey cycle |
| Direct label, range frame, sparkline | direct_label, annotate_point, apply_range_frame, sparkline |
| Choose colors when warranted | references/palettes.md |
| Final QA pass | references/checklist.md |
| Copyable plot patterns | examples/recipes.md |
| Duplicate figures in an executed Jupyter notebook | See the /notebooks troubleshooting section |
uv run --script skills/beautiful-data-viz/scripts/export_fixture.py skills/beautiful-data-viz/fixtures/growth_curve.csv --out build/fixture writes non-empty PNG, SVG, and PDF files with grey default series; with --background dark, labels inherit the dark-theme text color.from pathlib import Path
import sys
import matplotlib.pyplot as plt
SKILL_DIR = Path.home() / ".agents" / "skills" / "beautiful-data-viz"
sys.path.insert(0, str(SKILL_DIR))
from assets.beautiful_style import direct_label, finalize_axes, set_beautiful_style
cfg = set_beautiful_style(medium="paper", background="light")
fig, ax = plt.subplots(figsize=(4.2, 2.8))
for name, y in reference_series.items(): # context: default grey cycle
ax.plot(x, y, linewidth=1)
direct_label(ax, x, y, name)
ax.plot(x, treated, color=cfg.accent, linewidth=2) # the finding
direct_label(ax, x, treated, "Treated", color=cfg.accent)
finalize_axes(ax, xlabel="Time (days)", ylabel="Biomass (g/L)")
fig.savefig("growth.pdf")Issue: Labels overlap or are unreadable. Solution: Reduce tick count, wrap or abbreviate labels, switch to horizontal bars, or widen the figure.
Issue: Categories are hard to tell apart. Solution: Reduce the number of colored categories (group the rest in grey as "Other"), add markers or line styles, or split into small multiples.
Issue: A chart needs a legend, many colors, and a second y-axis to fit. Solution: Split it into small multiples with shared scales and direct labels.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.