<!-- Source: https://docs.biosimulant.com/references/library/visualization -->

# Visualization Contract

Standard format for module visualization output. Modules implement `visualize()` to return renderer-agnostic specs that Labs Serve UI and the platform render automatically.

## Timeseries

```python
def visualize(self):
    return {
        "render": "timeseries",
        "data": {
            "title": "Membrane Potential",
            "xlabel": "Time (ms)",
            "ylabel": "Voltage (mV)",
            "series": [
                {"name": "Neuron 1", "points": self.v1_history},
                {"name": "Neuron 2", "points": self.v2_history}
            ]
        }
    }
```

Each `points` entry is a list of `[x, y]` pairs: `[[0.0, -65.0], [0.1, -60.2], ...]`.

## Bar Chart

```python
def visualize(self):
    return {
        "render": "bar",
        "data": {
            "title": "Spike Counts",
            "items": [
                {"label": "Excitatory", "value": self.exc_count},
                {"label": "Inhibitory", "value": self.inh_count}
            ]
        }
    }
```

## Table

```python
def visualize(self):
    return {
        "render": "table",
        "data": {
            "columns": ["Metric", "Value"],
            "rows": [
                ["Mean Rate", f"{self.mean_rate:.2f} Hz"],
                ["Total Spikes", str(self.total_spikes)]
            ]
        }
    }
```

## Image (Raster Plot, Heatmap, etc.)

For complex visualizations generated with matplotlib or similar:

```python
def visualize(self):
    return {
        "render": "image",
        "data": {
            "src": self.raster_image_base64,  # data:image/png;base64,... or raw base64
            "alt": "Spike Raster",
            "width": 800,
            "height": 400
        }
    }
```

## Specification

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `render` | `str` | Yes | One of: `"timeseries"`, `"bar"`, `"table"`, `"image"` |
| `data` | `dict` | Yes | Render-type-specific content |

### Timeseries data

| Field | Type | Description |
|-------|------|-------------|
| `title` | `str` | Chart title |
| `xlabel` | `str` | X-axis label |
| `ylabel` | `str` | Y-axis label |
| `series` | `list[{name, points}]` | Named data series |

### Bar data

| Field | Type | Description |
|-------|------|-------------|
| `title` | `str` | Chart title |
| `items` | `list[{label, value}]` | Labeled values |

### Table data

| Field | Type | Description |
|-------|------|-------------|
| `columns` | `list[str]` | Column headers |
| `rows` | `list[list[str]]` | Row data (strings) |

### Image data

| Field | Type | Description |
|-------|------|-------------|
| `src` | `str` | Base64-encoded image (PNG/JPEG) |
| `alt` | `str` | Alt text |
| `width` | `int` | Display width in pixels |
| `height` | `int` | Display height in pixels |

## See Also

- [How to Add Custom Visualizations](/how-to/library/custom-visualizations): step-by-step guide
- [BioModule API](/references/library/biomodule-api): implementing `visualize()`
- [Artifact Outputs](/references/library/artifact-outputs): durable file outputs for structures and generated files
- [Labs Serve UI Reference](/references/library/labs-serve): rendering visualizations in the local lab UI
