Implementation:Iterative Dvc To Json
| Knowledge Sources | |
|---|---|
| Domains | Visualization, Output_Generation |
| Last Updated | 2026-02-10 00:00 GMT |
Overview
Concrete tool for serializing filled Vega-Lite renderer objects into JSON payloads and orchestrating HTML output generation, provided by the DVC library.
Description
The to_json function is the serialization endpoint of the DVC plot visualization pipeline. It takes a renderer object (either VegaRenderer or ImageRenderer from the dvc_render package) and converts it into a list of JSON-serializable dictionaries. For Vega-type renderers, it extracts the filled Vega-Lite template specification and the list of revisions. For image-type renderers, it produces one entry per image with the source URL and revision. The function supports a split mode where the Vega-Lite specification is returned with the data separated by revision, enabling clients to selectively display revision-specific data.
The CmdPlots.run method is the command-line entry point that orchestrates the entire output pipeline. It calls Plots.show or Plots.diff to collect data, passes it through match_defs_renderers to produce renderer objects, and then either serializes to JSON (via to_json and _show_json), outputs a raw Vega-Lite specification (via --show-vega), or generates an HTML file (via dvc_render.render_html). The HTML path produces a self-contained web page at <output_dir>/index.html that embeds all chart specifications with the Vega-Lite JavaScript runtime.
The output uses constants from dvc.render: TYPE_KEY ("type"), REVISIONS ("revisions"), REVISION ("rev"), and SRC ("src") to maintain a consistent JSON schema.
Usage
Use to_json when you need to serialize renderer objects into a JSON-compatible format for programmatic consumption (IDE extensions, APIs, CI/CD pipelines). Use CmdPlots.run as the full command-line entry point that handles target collection, data resolution, renderer matching, and output format selection.
Code Reference
Source Location
- Repository: DVC
- File:
dvc/render/convert.py - Lines: L21-49 (to_json)
- File:
dvc/commands/plots.py - Lines: L75-153 (CmdPlots.run)
Signature
def to_json(
renderer: "Renderer",
split: bool = False,
) -> list[dict]:
...
class CmdPlots(CmdBase):
def run(self) -> int:
...
Import
from dvc.render.convert import to_json
from dvc.commands.plots import CmdPlots
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| renderer | Renderer | Yes | A renderer object (VegaRenderer or ImageRenderer) from the dvc_render package, containing filled datapoints and template configuration. |
| split | bool | No | If True, the Vega-Lite specification is returned without inline data, and per-revision data arrays are provided separately. Defaults to False. |
| self.args.targets | list[str] | No | (For CmdPlots.run) Plot files or IDs to visualize. Empty means all plots. |
| self.args.json | bool | No | (For CmdPlots.run) If True, output JSON to stdout instead of generating HTML. |
| self.args.show_vega | bool | No | (For CmdPlots.run) If True, output the raw Vega-Lite specification for a single target. |
| self.args.out | Optional[str] | No | (For CmdPlots.run) Output directory for the generated HTML file. Defaults to "dvc_plots" from config. |
| self.args.open | bool | No | (For CmdPlots.run) If True, open the generated HTML file in the default browser. |
| self.args.split | bool | No | (For CmdPlots.run) Passed through to to_json for split-mode JSON output. |
Outputs
| Name | Type | Description |
|---|---|---|
| result | list[dict] | (From to_json) For Vega renderers: a single-element list containing {"type": "vega", "revisions": [...], "content": {vega_lite_spec}, ...optional_split_data}. For image renderers: a multi-element list where each dict contains {"type": "image", "revisions": [rev], "url": src_url}. |
| return_code | int | (From CmdPlots.run) Exit code: 0 on success, 1 on error. Side effects include writing JSON to stdout, writing HTML to disk, or opening a browser. |
Usage Examples
Basic Usage
from dvc.repo import Repo
from dvc.render.match import match_defs_renderers
from dvc.render.convert import to_json
repo = Repo()
# Collect and resolve plot data
plots_data = repo.plots.show(targets=["metrics.csv"])
# Create renderers
renderers_with_errors = match_defs_renderers(
data=plots_data,
templates_dir=repo.plots.templates_dir,
)
# Serialize each renderer to JSON
for rwe in renderers_with_errors:
json_payload = to_json(rwe.renderer, split=False)
for entry in json_payload:
print(f"Type: {entry['type']}")
print(f"Revisions: {entry['revisions']}")
if entry['type'] == 'vega':
spec = entry['content']
print(f"Vega-Lite schema: {spec.get('$schema', 'N/A')}")
Split Mode for IDE Integration
from dvc.render.convert import to_json
# Assuming renderer is a VegaRenderer with multi-revision data
json_payload = to_json(renderer, split=True)
entry = json_payload[0]
# entry["content"] contains the Vega-Lite spec without data values
# entry also contains split per-revision data arrays
# This allows IDE extensions to toggle revisions dynamically
print(f"Revisions available: {entry['revisions']}")
HTML Output via Command Line
# From the command line (not Python API):
# dvc plots show --out my_plots
# Generates my_plots/index.html with embedded Vega-Lite specs
# dvc plots diff v1.0 v2.0 --json
# Outputs JSON to stdout with all renderers serialized
# dvc plots show metrics.csv --show-vega
# Outputs raw Vega-Lite JSON spec for the specified target
Full Pipeline Example
import json
from dvc.repo import Repo
from dvc.render.match import match_defs_renderers
from dvc.render.convert import to_json
from dvc_render import render_html
from pathlib import Path
repo = Repo()
# Step 1: Collect plots across revisions
plots_data = repo.plots.diff(
targets=None,
revs=["main", "experiment-branch"],
props={"template": "linear"},
)
# Step 2: Match to renderers
renderers_with_errors = match_defs_renderers(
data=plots_data,
out="output/static",
templates_dir=repo.plots.templates_dir,
)
# Step 3a: JSON output for API consumption
output = {}
for rwe in renderers_with_errors:
output[rwe.renderer.name] = to_json(rwe.renderer, split=False)
print(json.dumps(output, indent=2))
# Step 3b: HTML output for browser viewing
renderers = [rwe.renderer for rwe in renderers_with_errors]
output_file = Path("output/index.html")
render_html(
renderers=renderers,
output_file=output_file,
)
print(f"HTML visualization: {output_file.as_uri()}")