Adapt Visualisation¶
Adapt Visualisation — mvp.adapt_visualisation
Cluster: Creative & Media | Type: component | MCP Tools: 46
Overview¶
Matplotlib/Seaborn chart generation block that turns a list of row dicts into line, bar, scatter, histogram, box, or heatmap charts with configurable axes, titles, figure size, and visual style. Output is either a base64-encoded PNG (suitable for embedding in reports or API responses) or a file saved to a given path. Field names are auto-detected from the data when not specified, keeping usage minimal for quick exploratory plots.
Dependency caveat: matplotlib is the primary rendering backend and is required for image charts and animations. If matplotlib is unavailable, the core block returns a structured text fallback with summary statistics instead of an image. seaborn is optional: heatmaps, violin plots, regression plots, and KDE overlays use it when installed, but fall back to matplotlib-only rendering when it is missing. For polished launch demos and customer-facing reports, install both:
Use the MCP backend_capabilities tool to confirm backend availability, export formats, styles, disabled optional features, and resource limits before relying on advanced styling. Backend-native tools (backend_validate_spec, backend_render_spec, backend_export, backend_style_preview) accept only a constrained JSON grammar and return loud degradation envelopes for missing dependencies, blocked paths, unsupported formats, and rejected spec nodes.
Contract posture: production harness allow-list rollout is blocked-escalated until the policy owner approves editing policies/production_harnesses.yaml. Local state surfaces are chart rendering, optional backend detection, optional history storage, style registry, and export policy. Extension points are curated chart ops, backend-native spec ops, capability discovery, degradation normalization, and advisory recommendations.
When to use:
- Visualising evaluation metric histories or training curves produced by ML blocks
- Generating data-driven charts for pipeline reports or MCP tool outputs
- Producing heatmaps of correlation matrices or confusion matrices from evaluation blocks
- Quickly plotting any list of row dicts without writing matplotlib boilerplate
Example:
from mvp.adapt_visualisation import AdaptVisualisationBlock, VisualisationInput
block = AdaptVisualisationBlock(name="vis")
result = block.infer(VisualisationInput(
data=[{"epoch": 1, "loss": 0.8}, {"epoch": 2, "loss": 0.5}, {"epoch": 3, "loss": 0.3}],
chart_type="line",
x_field="epoch",
y_field="loss",
title="Training Loss",
))
# result.value.figure_base64 → base64 PNG of the chart
Works well with: adapt_diagrams, align_evals, adapt_pandas
Public API¶
ChartRecommendationProfile¶
Bounded profile that drives the chart-type recommendation.
| Field | Type | Default |
|---|---|---|
numeric_fields | tuple[str, ...] | () |
categorical_fields | tuple[str, ...] | () |
row_count | int | 0 |
negative_numeric_fields | tuple[str, ...] | () |
intent | str | '' |
x_field | str | '' |
Methods:
from_input(data_rows: list[dict], intent: str = '', x_field: str = '') -> 'ChartRecommendationProfile'¶
Build a profile from a parsed list-of-row-dicts dataset + caller intent.
n_numeric() -> int¶
n_categorical() -> int¶
has_nonnegative_numeric() -> bool¶
True iff at least one numeric field has NO negative value (a valid pie value
ChartRecommendation¶
Decision record for a ranked chart-type recommendation.
| Field | Type | Default |
|---|---|---|
ranked | tuple[str, ...] | () |
rationale | str | '' |
confidence | float | 0.0 |
completion_state | str | 'qualified-draft' |
degraded | bool | False |
degradation_reason | str | '' |
raw_response | str | '' |
metadata | dict[str, Any] | field(default_factory=dict) |
Methods:
choice() -> str¶
The top-ranked (recommended) chart type, or '' if none eligible.
LLMChartRuntime¶
Provider-neutral chart-recommendation runtime backed by G6's LLM caller.
Constructor:
| Parameter | Type | Default |
|---|---|---|
llm | LLMCaller \| None | None |
Methods:
recommend(profile: ChartRecommendationProfile, eligible: tuple[str, ...]) -> ChartRecommendation¶
ChartPlanner¶
Runtime-first facade with the real deterministic recommender as fallback.
Constructor:
| Parameter | Type | Default |
|---|---|---|
runtime | ChartRuntime \| None | None |
Methods:
recommend(profile: ChartRecommendationProfile) -> ChartRecommendation¶
AnimationBlock(AIBlock[AnimationInput, AnimationOutput, None])¶
Matplotlib animation generator.
| Field | Type | Default |
|---|---|---|
name | str | 'animation' |
resource_bounds | ResourceBounds \| None | None |
usage | ResourceUsage | field(default_factory=ResourceUsage) |
Methods:
infer(data: AnimationInput) -> Result[AnimationOutput]¶
AnimationInput(BaseModel)¶
Input for animation generation.
| Field | Type | Default |
|---|---|---|
op | Literal['anim_line_trace', 'anim_bar_race', 'anim_scatter_morph', 'anim_heatmap_evolution', 'anim_custom'] | required |
data | list[dict[str, object]] | required |
x_field | str | '' |
y_field | str | '' |
time_field | str | '' |
group_field | str | '' |
value_field | str | '' |
title | str | 'Animation' |
x_label | str | '' |
y_label | str | '' |
output_path | str | '' |
output_format | Literal['gif', 'mp4', 'html'] | 'gif' |
figsize | list[float] | Field(default_factory=lambda: [8.0, 5.0]) |
fps | int | Field(default=10, ge=1, le=60) |
interval_ms | int | Field(default=100, ge=1, le=60000) |
frames | int | Field(default=0, ge=0, le=1000) |
style | str | 'default' |
cmap | str | 'viridis' |
custom_update_expr | str | '' |
AnimationOutput(BaseModel)¶
Output from animation generation.
| Field | Type | Default |
|---|---|---|
op | str | required |
title | str | '' |
n_frames | int | 0 |
output_path | str | '' |
figure_base64 | str | '' |
format | str | '' |
fps | int | 0 |
duration_seconds | float | 0.0 |
summary | str | '' |
backend | str | '' |
VisualisationInput(BaseModel)¶
Input to AdaptVisualisationBlock.
| Field | Type | Default |
|---|---|---|
data | list[dict[str, object]] | required |
chart_type | Literal['line', 'bar', 'scatter', 'histogram', 'box', 'heatmap'] | 'bar' |
x_field | str | '' |
y_field | str | '' |
title | str | 'Chart' |
x_label | str | '' |
y_label | str | '' |
output_path | str | '' |
style | str | 'default' |
figsize | list[float] | Field(default_factory=lambda: [8.0, 5.0]) |
VisualisationOutput(BaseModel)¶
Output from AdaptVisualisationBlock.
| Field | Type | Default |
|---|---|---|
chart_type | str | required |
title | str | required |
n_data_points | int | required |
x_field | str | required |
y_field | str | required |
output_path | str | '' |
figure_base64 | str | '' |
summary | str | required |
backend | str | 'matplotlib' |
degraded | bool | False |
degradation_reason | str | '' |
completion_state | Literal['verified', 'qualified-draft', 'blocked-escalated'] | 'qualified-draft' |
warning_card | dict | Field(default_factory=dict) |
evidence | list[dict] | Field(default_factory=list) |
request_id | str | '' |
task_id | str | '' |
run_id | str | '' |
AdaptVisualisationBlock(AIBlock[VisualisationInput, VisualisationOutput, None])¶
Matplotlib/seaborn chart generator.
| Field | Type | Default |
|---|---|---|
name | str | 'adapt_visualisation' |
resource_bounds | ResourceBounds \| None | None |
usage | ResourceUsage | field(default_factory=ResourceUsage) |
Methods:
infer(data: VisualisationInput) -> Result[VisualisationOutput]¶
MCPVisualisationInput(BaseModel)¶
| Field | Type | Default |
|---|---|---|
op | Literal['chart_bar', 'chart_line', 'chart_scatter', 'chart_histogram', 'chart_box', 'chart_heatmap', 'chart_pie', 'chart_area', 'chart_violin', 'chart_regression', 'chart_correlation', 'chart_multi', 'dataset_register', 'dataset_list', 'dataset_delete', 'chart_history', 'chart_get', 'chart_delete', 'history_purge', 'style_list', 'get_info', 'anim_line_trace', 'anim_bar_race', 'anim_scatter_morph', 'anim_heatmap_evolution', 'anim_custom', 'recommend_chart', 'list_patterns', 'backend_capabilities', 'backend_validate_spec', 'backend_render_spec', 'backend_export', 'backend_style_preview'] | required |
data_json | str | '[]' |
intent | str | '' |
x_field | str | '' |
y_field | str | '' |
y_fields_json | str | '[]' |
fields_json | str | '[]' |
color_field | str | '' |
size_field | str | '' |
label_field | str | '' |
value_field | str | '' |
group_field | str | '' |
title | str | 'Chart' |
style | str | 'default' |
output_path | str | '' |
figsize_json | str | '[8.0, 5.0]' |
color | str | '' |
cmap | str | 'viridis' |
horizontal | bool | False |
bins | int | 0 |
kde | bool | False |
donut | bool | False |
stacked | bool | False |
ci | int | 95 |
annot | bool | True |
specs_json | str | '[]' |
nrows | int | 1 |
ncols | int | 2 |
name | str | '' |
notes | str | '' |
chart_id | str | '' |
limit | int | 20 |
time_field | str | '' |
output_format | Literal['gif', 'mp4', 'html'] | 'gif' |
fps | int | Field(default=10, ge=1, le=60) |
interval_ms | int | Field(default=100, ge=1, le=60000) |
frames | int | Field(default=0, ge=0, le=1000) |
export_format | str | 'png' |
accessible_colors | bool | False |
spec | dict | Field(default_factory=dict) |
backend_id | str | '' |
dry_run | bool | False |
request_id | str | '' |
task_id | str | '' |
run_id | str | '' |
MCPVisualisationOutput(BaseModel)¶
| Field | Type | Default |
|---|---|---|
op | str | required |
ok | bool | True |
message | str | '' |
chart_id | str | '' |
chart_type | str | '' |
title | str | '' |
x_field | str | '' |
y_field | str | '' |
n_data_points | int | 0 |
output_path | str | '' |
figure_base64 | str | '' |
summary | str | '' |
backend | str | '' |
charts | list[dict] | Field(default_factory=list) |
datasets | list[dict] | Field(default_factory=list) |
styles | list[str] | Field(default_factory=list) |
metadata | dict | Field(default_factory=dict) |
count | int | 0 |
degraded | bool | False |
degradation_reason | str | '' |
completion_state | Literal['verified', 'qualified-draft', 'blocked-escalated'] | 'qualified-draft' |
warning_card | dict | Field(default_factory=dict) |
evidence | list[dict] | Field(default_factory=list) |
request_id | str | '' |
task_id | str | '' |
run_id | str | '' |
n_frames | int | 0 |
format | str | '' |
duration_seconds | float | 0.0 |
VisualisationStore¶
Constructor:
| Parameter | Type | Default |
|---|---|---|
db_path | str | ':memory:' |
Methods:
insert_chart(op: str, title: str = '', x_field: str = '', y_field: str = '', backend: str = '', n_data_points: int = 0, output_path: str = '', figure_base64: str = '', summary: str = '', dataset_name: str = '', notes: str = '') -> str¶
list_charts(limit: int = 20, op: str = '') -> list[dict]¶
get_chart(chart_id: str) -> dict | None¶
delete_chart(chart_id: str) -> bool¶
purge_old_charts(ttl_hours: int = 168) -> int¶
Delete charts older than ttl_hours. ttl_hours=0 deletes all. Returns deleted count.
upsert_dataset(name: str, records: list[dict], notes: str = '') -> None¶
get_dataset(name: str) -> list[dict] | None¶
list_datasets(limit: int = 20) -> list[dict]¶
delete_dataset(name: str) -> bool¶
count_all() -> dict[str, int]¶
AdaptVisualisationMCPBlock(AIBlock[MCPVisualisationInput, MCPVisualisationOutput, dict])¶
33-op visualisation MCP block backed by SQLite.
| Field | Type | Default |
|---|---|---|
name | str | 'adapt_visualisation_mcp' |
db_path | str | ':memory:' |
resource_bounds | ResourceBounds \| None | None |
usage | ResourceUsage | field(default_factory=ResourceUsage) |
agentic_planner | 'ChartPlanner \| None' | None |
Methods:
infer(data: MCPVisualisationInput) -> Result[MCPVisualisationOutput]¶
Functions¶
agentic_planner_enabled(default_enabled: bool, llm_backend: str | None = None) -> bool¶
Decide whether the agentic recommendation planner should be used.
eligible_charts(profile: ChartRecommendationProfile) -> list[str]¶
FIXED eligible-set ceiling, computed DETERMINISTICALLY (no LLM).
deterministic_chart_recommend(profile: ChartRecommendationProfile) -> ChartRecommendation¶
Demoted-real column-COUNT ranking, intersected with the eligible ceiling.
MCP Tools¶
| Operation | Source |
|---|---|
line | visualisation_mcp |
bar | visualisation_mcp |
scatter | visualisation_mcp |
histogram | visualisation_mcp |
box | visualisation_mcp |
heatmap | visualisation_mcp |
area | visualisation_mcp |
step | visualisation_mcp |
errorbar | visualisation_mcp |
matplotlib | visualisation_mcp |
chart_bar | visualisation_mcp |
chart_line | visualisation_mcp |
chart_scatter | visualisation_mcp |
chart_histogram | visualisation_mcp |
chart_box | visualisation_mcp |
chart_heatmap | visualisation_mcp |
chart_pie | visualisation_mcp |
chart_area | visualisation_mcp |
chart_violin | visualisation_mcp |
chart_regression | visualisation_mcp |
chart_correlation | visualisation_mcp |
chart_multi | visualisation_mcp |
dataset_register | visualisation_mcp |
dataset_list | visualisation_mcp |
dataset_delete | visualisation_mcp |
chart_history | visualisation_mcp |
chart_get | visualisation_mcp |
chart_delete | visualisation_mcp |
history_purge | visualisation_mcp |
style_list | visualisation_mcp |
get_info | visualisation_mcp |
anim_line_trace | visualisation_mcp |
anim_bar_race | visualisation_mcp |
anim_scatter_morph | visualisation_mcp |
anim_heatmap_evolution | visualisation_mcp |
anim_custom | visualisation_mcp |
recommend_chart | visualisation_mcp |
list_patterns | visualisation_mcp |
backend_capabilities | visualisation_mcp |
backend_validate_spec | visualisation_mcp |
backend_render_spec | visualisation_mcp |
backend_export | visualisation_mcp |
backend_style_preview | visualisation_mcp |
gif | visualisation_mcp |
mp4 | visualisation_mcp |
html | visualisation_mcp |