> ## Documentation Index
> Fetch the complete documentation index at: https://heygen-1fa696a7.mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Visualization Videos

> Convert spreadsheets, dashboards, and analytics into avatar-led explainer videos via the HeyGen API. The agent narrates the data and surfaces the key findings.

## Examples

<Tabs>
  <Tab title="Sorting Algorithms">
    <div style={{maxWidth: "350px", margin: "0 auto"}}>
      <iframe src="https://www.loom.com/embed/81b5147ad14c4bab86d1c2a6111b9f31" frameBorder="0" allowFullScreen style={{width: "100%", height: "620px", borderRadius: "8px"}} />
    </div>

    9 sorting algorithms on 100 bars — bubble sort through merge sort. Each comparison plays a pitched tone. 76 seconds with synthesized audio.
  </Tab>

  <Tab title="4000 Weeks">
    <div style={{maxWidth: "350px", margin: "0 auto"}}>
      <iframe src="https://www.loom.com/embed/b5ca0df53f2640feb563c584cadcd944" frameBorder="0" allowFullScreen style={{width: "100%", height: "620px", borderRadius: "8px"}} />
    </div>

    A 75-year life as 3,900 weekly squares. They fill in with an accelerating heartbeat. The empty ones are what's left.
  </Tab>

  <Tab title="Flappy Bird">
    <div style={{maxWidth: "350px", margin: "0 auto"}}>
      <iframe src="https://www.loom.com/embed/7494178af30449dc8a24903116bfb79b" frameBorder="0" allowFullScreen style={{width: "100%", height: "620px", borderRadius: "8px"}} />
    </div>

    A full Flappy Bird game playing itself — pixel art, auto-pilot AI, wing flap sounds, score dings. 33 seconds. No game engine, just HTML + math.
  </Tab>
</Tabs>

## The Problem

Data tells a story, but spreadsheets and static charts don't. Animated visualizations are compelling — but building them as shareable video (not just an interactive webpage) usually means screen recording with all its artifacts.

## How It Works

```
Data source → Generate visualization HTML → Animate with GSAP → Render to MP4
```

Hyperframes renders anything a browser can display. D3 charts, Canvas graphics, SVG diagrams, CSS animations — they all become pixel-perfect video frames.

## Build It

<Steps>
  <Step title="Prepare your data">
    Your data can come from anywhere — a CSV, an API, a database, or generated programmatically.

    ```python theme={null}
    # Example: pull GitHub stats
    import requests

    repos = requests.get(
        "https://api.github.com/users/your-username/repos",
        headers={"Authorization": f"token {GITHUB_TOKEN}"}
    ).json()

    stats = {
        "total_repos": len(repos),
        "languages": {},
        "total_stars": sum(r["stargazers_count"] for r in repos),
    }
    for r in repos:
        lang = r.get("language") or "Other"
        stats["languages"][lang] = stats["languages"].get(lang, 0) + 1
    ```
  </Step>

  <Step title="Describe the visualization to your AI agent">
    ```
    I have GitHub data for a developer: 13 repos, 472 commits,
    top languages are TypeScript (5), Dart (3), JavaScript (1).

    Create a "GitHub Wrapped" style video — vertical 9:16, 45 seconds.
    Show the stats one by one with animated counters, a bar chart of
    languages that grows, and end with a highlight reel of project names.
    Use a dark theme with green (#00ff88) accents like GitHub's contribution graph.
    ```

    The AI agent writes the HTML composition with the data baked into the animation.
  </Step>

  <Step title="Add generated audio (optional)">
    For data visualizations, synthesized audio often works better than voiceover. You can generate tones programmatically:

    ```python theme={null}
    import wave, struct, math

    # Generate pitched tones for a sorting visualizer
    sample_rate = 44100
    samples = []
    for value in data_points:
        freq = 200 + (value / max_value) * 1000  # pitch = data value
        for i in range(int(0.03 * sample_rate)):  # 30ms per tone
            env = 1.0 - (i / (0.03 * sample_rate)) * 0.7
            s = env * 0.25 * math.sin(2 * math.pi * freq * i / sample_rate)
            samples.append(s)

    with wave.open("data-sound.wav", "w") as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(sample_rate)
        for s in samples:
            wf.writeframes(struct.pack("<h", int(max(-1, min(1, s)) * 32767)))
    ```

    Then reference it in the composition:

    ```html theme={null}
    <audio id="data-sfx" data-start="0" data-track-index="5"
           data-volume="0.8" src="data-sound.wav"></audio>
    ```
  </Step>

  <Step title="Preview and render">
    ```bash theme={null}
    npx hyperframes dev    # preview at localhost:3002
    npx hyperframes render # export to MP4
    ```
  </Step>
</Steps>

## Visualization Ideas

| Type                        | What it looks like                               | Complexity                            |
| --------------------------- | ------------------------------------------------ | ------------------------------------- |
| **Animated bar chart**      | Bars growing, sorting, racing                    | Simple — CSS + GSAP                   |
| **Counter/ticker**          | Numbers rolling up from 0 to target              | Simple — GSAP snap                    |
| **Line chart drawing**      | SVG polyline with stroke-dashoffset animation    | Medium — SVG + GSAP                   |
| **Dashboard**               | Multiple panels updating simultaneously          | Medium — layout + timing              |
| **Algorithm visualization** | Sorting bars, pathfinding grids, tree traversals | Complex — pre-compute states, animate |
| **Physics simulation**      | Bouncing balls, pendulum waves, particle systems | Complex — math-driven positions       |

## Automate It

The real power: **data in, video out** as a pipeline.

```python theme={null}
import subprocess

def generate_data_video(data, template_dir, output_path):
    """Generate a video from data using Hyperframes."""

    # 1. Write data into the composition
    with open(f"{template_dir}/data.json", "w") as f:
        json.dump(data, f)

    # 2. Render
    subprocess.run([
        "npx", "hyperframes", "render",
        "--output", output_path,
        "--quality", "standard"
    ], cwd=template_dir)

    return output_path

# Generate weekly report videos from database
for week in get_weekly_metrics():
    generate_data_video(
        data=week,
        template_dir="templates/weekly-report",
        output_path=f"renders/report-{week['date']}.mp4"
    )
```

<Tip>
  Combine with [Docs to Video](/cookbook/video-agent/docs-to-video) for a fully automated pipeline: data changes → Hyperframes renders visualization → Video Agent adds avatar narration.
</Tip>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Motion Graphics" icon="wand-magic-sparkles" href="/cookbook/hyperframes/motion-graphics">
    Animated title cards, product launches, and brand content.
  </Card>

  <Card title="Automated Pipeline" icon="gears" href="/cookbook/hyperframes/automated-pipeline">
    CI/CD integration for continuous video generation from data.
  </Card>
</CardGroup>
