Chart Generation¶
This guide covers how to write chart code for ExpOps. For configuration details, see Reporting Features.
Static Charts¶
Static charts generate PNG image files that are saved to disk.
Configuration: Chart entrypoints are configured in project_config.yaml under reporting.static_entrypoint. See Reporting Features for configuration details.
Chart Functions¶
Functions decorated with @chart() generate visualizations. Chart functions have strict requirements:
Required Function Signature¶
Every static chart function MUST:
- Accept
metricsas the first parameter (Dict[str, Any]) - Accept
ctxas the second parameter (ChartContext) - Use
ctx.savefig()to save figures
from mlops.reporting import chart, ChartContext
from typing import Dict, Any
import matplotlib.pyplot as plt
@chart()
def plot_metrics(metrics: Dict[str, Any], ctx: ChartContext) -> None:
"""
Chart function signature requirements:
- metrics: Dict containing metrics from probe_paths (REQUIRED)
- ctx: ChartContext for saving figures (REQUIRED)
- Returns: None (void function)
"""
# Access metrics directly from the metrics dict
# Metrics are keyed by probe_path keys from project_config.yaml
train_metrics = metrics.get('train', {})
eval_metrics = metrics.get('eval', {})
# Extract specific metric values
train_acc = train_metrics.get('accuracy', {})
eval_acc = eval_metrics.get('accuracy', {})
# Generate matplotlib plot
fig, ax = plt.subplots(figsize=(10, 6))
# ... plotting code ...
# MUST use ctx.savefig() to save the figure
ctx.savefig('plot_metrics.png', fig=fig, dpi=150)
plt.close(fig)
Note: The function name should match the chart name defined in project_config.yaml, or be registered via the @chart() decorator.
Metrics Access¶
Metrics are passed directly to chart functions via the metrics parameter:
- Metrics structure: The
metricsdict is keyed by the probe_path keys fromproject_config.yaml - Access pattern:
metrics.get('probe_key', {})returns metrics from that probe path - Metric values: Each probe path contains metrics logged from that process/step
- Step-based metrics: Metrics logged with
step=parameter are stored as dicts like{"1": value1, "2": value2, ...}
Example:
Given this config:
The chart function receives:
@chart()
def my_chart(metrics: Dict[str, Any], ctx: ChartContext) -> None:
# metrics['train'] contains metrics from train_model process
train_data = metrics.get('train', {})
# metrics['eval'] contains metrics from evaluate_model process
eval_data = metrics.get('eval', {})
# Access specific metrics (may be dicts if logged with step=)
train_acc = train_data.get('accuracy', {})
eval_acc = eval_data.get('accuracy', {})
Output¶
Static charts produce image files (PNG) saved to:
Dynamic Charts¶
Dynamic charts provide real-time, interactive visualizations.
Configuration: Chart entrypoints are configured in project_config.yaml under reporting.dynamic_entrypoint. See Reporting Features for configuration details.
Example¶
// Subscribe to metrics
subscribeToMetrics((metrics) => {
// Update Chart.js chart
chart.data.datasets[0].data = metrics;
chart.update();
});
Chart Dependencies¶
Chart dependencies are configured separately from the main project dependencies to reduce training environment overhead.
Configuration¶
Chart dependencies are specified in project_config.yaml:
environment:
venv:
reporting:
name: "my-project-env-reporting"
requirements_file: "projects/my-project/charts/requirements.txt"
The requirements_file path is relative to the workspace root. This allows you to:
- Keep visualization libraries separate from training dependencies
- Use minimal dependencies for chart generation
- Include libraries like matplotlib, seaborn, plotly, etc.