Helper Utilities (dm.helpers)

General-purpose helpers for building consistent, high-quality visualizations. They cover the small ergonomic gaps that show up between matplotlib and a polished figure — data validation, color picking, label/legend formatting, quality checks, and figure I/O.

These helpers compose well with the rest of dartwork-mpl, but they also work as a standalone toolkit on top of plain matplotlib.

Note

Module renames you may still run into. The helpers module was previously called agent_utils (renamed in v0.2.0), and its formatting submodule was renamed to dartwork_mpl.helpers.labels in the v0.3.x series to avoid clashing with the top-level dartwork_mpl.formatting (axis tick formatters). Both old paths still work but emit a DeprecationWarning — see the Migration Guide for one-shot migration scripts.

Overview

The helpers module is organized into specialized submodules:

  • data: Data validation and cleaning utilities

  • colors: Automatic color selection and management

  • labels: Axis labels, legends, and value annotations

  • quality: Quality checks and chart suggestions

  • io: Figure creation and saving utilities

Main Module

General-purpose helper utilities for dartwork-mpl.

Composition helpers that sit above the low-level matplotlib and dartwork-mpl primitives. This module is organised into submodules:

  • data: data validation and cleaning.

  • colors: palette selection.

  • labels: axis-label / legend / value-annotation helpers.

  • quality: figure quality checks and chart-type suggestion.

  • io: styled figure creation and optimised save.

dartwork_mpl.helpers.check_figure_quality(fig: Figure) list[str][source]

Check figure for common quality issues.

Parameters:

fig (Figure) – Figure to check

Returns:

List of issues found

Return type:

list[str]

Examples

>>> issues = check_figure_quality(fig)
>>> if issues:
...     print("Quality issues found:")
...     for issue in issues:
...         print(f"  - {issue}")
dartwork_mpl.helpers.make_palette(n: int, kind: Literal['categorical', 'sequential', 'diverging'] = 'categorical', highlight: int | None = None) list[str][source]

Return n curated dartwork color names for kind series.

Parameters:
  • n (int) – Number of series the palette must cover. Colors repeat if n exceeds the built-in list for kind.

  • kind ({"categorical", "sequential", "diverging"}) – Palette family. categorical returns distinct hues; sequential returns light→dark blues; diverging returns red↔blue through gray.

  • highlight (int | None) – If set, the series at this index becomes darker (oc.*7) and the rest become lighter (oc.*3) to emphasise it. Only effective for the categorical and (loosely) diverging palettes whose names contain a "5" middle shade.

Returns:

Length-n list of dartwork color names.

Return type:

list[str]

Examples

>>> make_palette(5)                           # 5 categorical series
>>> make_palette(3, kind="sequential")        # 3 sequential blues
>>> make_palette(4, highlight=0)              # emphasise series 0
dartwork_mpl.helpers.optimize_legend(ax: Axes, preferred_loc: str = 'best', max_cols: int = 3, outside: bool = False) None[source]

Optimize legend placement and formatting.

Parameters:
  • ax (Axes) – Matplotlib axes

  • preferred_loc (str) – Preferred location if space permits

  • max_cols (int) – Maximum number of columns for legend

  • outside (bool) – Whether to place legend outside plot area

Examples

>>> optimize_legend(ax, preferred_loc="upper right")
>>> optimize_legend(ax, outside=True)
dartwork_mpl.helpers.suggest_chart_type(x_type: str, y_type: str | None, n_points: int, n_series: int = 1) str[source]

Suggest appropriate chart type based on data characteristics.

Parameters:
  • x_type (str) – Type of x data: “continuous”, “categorical”, “temporal”

  • y_type (str | None) – Type of y data: “continuous”, “categorical”, “count”, None

  • n_points (int) – Number of data points

  • n_series (int) – Number of data series

Returns:

Suggested chart type

Return type:

str

Examples

>>> chart_type = suggest_chart_type("categorical", "continuous", 5, 1)
>>> print(chart_type)  # "bar"
dartwork_mpl.helpers.validate_data(x: Any, y: Any | None = None, require_same_length: bool = True, allow_nan: bool = False, min_points: int = 2) tuple[ndarray[Any, Any], ndarray[Any, Any] | None][source]

Validate and clean input data for plotting.

Parameters:
  • x (Any) – X-axis data

  • y (Any | None) – Y-axis data (optional for histograms, etc.)

  • require_same_length (bool) – Whether x and y must have the same length

  • allow_nan (bool) – Whether to allow NaN values

  • min_points (int) – Minimum number of data points required

Returns:

Cleaned x and y arrays

Return type:

tuple[np.ndarray, np.ndarray | None]

Raises:

ValueError – If validation fails

Examples

>>> x, y = validate_data([1, 2, 3], [4, 5, 6])
>>> x_clean, _ = validate_data([1, 2, np.nan, 4], allow_nan=False)

Data Validation

Utilities for validating and cleaning data before plotting.

Data validation and cleaning utilities for dartwork-mpl agents.

This module provides functions for validating and cleaning data before plotting.

dartwork_mpl.helpers.data.validate_data(x: Any, y: Any | None = None, require_same_length: bool = True, allow_nan: bool = False, min_points: int = 2) tuple[ndarray[Any, Any], ndarray[Any, Any] | None][source]

Validate and clean input data for plotting.

Parameters:
  • x (Any) – X-axis data

  • y (Any | None) – Y-axis data (optional for histograms, etc.)

  • require_same_length (bool) – Whether x and y must have the same length

  • allow_nan (bool) – Whether to allow NaN values

  • min_points (int) – Minimum number of data points required

Returns:

Cleaned x and y arrays

Return type:

tuple[np.ndarray, np.ndarray | None]

Raises:

ValueError – If validation fails

Examples

>>> x, y = validate_data([1, 2, 3], [4, 5, 6])
>>> x_clean, _ = validate_data([1, 2, np.nan, 4], allow_nan=False)

Example:

import dartwork_mpl as dm
import numpy as np

# Validate data before plotting
x = np.array([1, 2, np.nan, 4, 5])
y = np.array([2, 4, 6, 8, 10])

x_clean, y_clean = dm.helpers.data.validate_data(
    x, y,
    require_same_length=True,
    allow_nan=False,
    min_points=3
)

Palette Lookup

Curated dartwork palette sized to the data series count and kind.

Curated palette lookup for dartwork-mpl.

make_palette returns a list of dartwork color names sized to the requested series count and palette kind. The four built-in lists (categorical, sequential blue at two cardinalities, diverging red-blue at two cardinalities) are the dartwork-mpl recommended series colors; they live inside this function so the project’s palette curation stays centralised.

Renamed from auto_select_colors in 0.5 (#156 Round 5):

  • auto_ prefix collided with auto_layout (measure-and-adjust).

  • select_colors was a strong verb for what is structurally a list slice.

  • palette is the existing domain term used by list_palettes and show_palette.

dartwork_mpl.helpers.colors.make_palette(n: int, kind: Literal['categorical', 'sequential', 'diverging'] = 'categorical', highlight: int | None = None) list[str][source]

Return n curated dartwork color names for kind series.

Parameters:
  • n (int) – Number of series the palette must cover. Colors repeat if n exceeds the built-in list for kind.

  • kind ({"categorical", "sequential", "diverging"}) – Palette family. categorical returns distinct hues; sequential returns light→dark blues; diverging returns red↔blue through gray.

  • highlight (int | None) – If set, the series at this index becomes darker (oc.*7) and the rest become lighter (oc.*3) to emphasise it. Only effective for the categorical and (loosely) diverging palettes whose names contain a "5" middle shade.

Returns:

Length-n list of dartwork color names.

Return type:

list[str]

Examples

>>> make_palette(5)                           # 5 categorical series
>>> make_palette(3, kind="sequential")        # 3 sequential blues
>>> make_palette(4, highlight=0)              # emphasise series 0

Example:

import dartwork_mpl as dm

# Curated palette for 5 categorical series, item 0 highlighted.
colors = dm.make_palette(5, kind="categorical", highlight=0)

# Plot with the palette
for i, color in enumerate(colors):
    ax.plot(x, data[i], color=color, label=f"Series {i+1}")

Label, Legend, and Annotation Helpers

Functions for composing axis labels, placing legends, and adding value annotations.

Label and legend helpers.

Higher-level composition helpers for legend placement. Renamed from helpers.formatting to avoid the name clash with the top-level dartwork_mpl.formatting module (which houses the format_axis_* tick formatters).

For axis labels, use ax.set_xlabel / ax.set_ylabel directly. For per-point value annotations, use an ax.text loop inline.

dartwork_mpl.helpers.labels.optimize_legend(ax: Axes, preferred_loc: str = 'best', max_cols: int = 3, outside: bool = False) None[source]

Optimize legend placement and formatting.

Parameters:
  • ax (Axes) – Matplotlib axes

  • preferred_loc (str) – Preferred location if space permits

  • max_cols (int) – Maximum number of columns for legend

  • outside (bool) – Whether to place legend outside plot area

Examples

>>> optimize_legend(ax, preferred_loc="upper right")
>>> optimize_legend(ax, outside=True)

Example:

import dartwork_mpl as dm
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(x, y)

# Format axis labels automatically
dm.helpers.labels.format_axis_labels(
    ax,
    xlabel="Time",
    ylabel="Value",
    use_latex=False
)

# Optimize legend placement
dm.helpers.labels.optimize_legend(
    ax,
    loc='best',
    frameon=False
)

# Add value labels to data points
dm.helpers.labels.add_value_labels(
    ax,
    x, y,
    format_str="{:.1f}",
    offset=(0, 5)
)

Quality Checks

Functions for checking figure quality and suggesting improvements.

Quality checks and chart type suggestions for dartwork-mpl agents.

This module provides functions for checking figure quality and suggesting appropriate chart types based on data characteristics.

dartwork_mpl.helpers.quality.check_figure_quality(fig: Figure) list[str][source]

Check figure for common quality issues.

Parameters:

fig (Figure) – Figure to check

Returns:

List of issues found

Return type:

list[str]

Examples

>>> issues = check_figure_quality(fig)
>>> if issues:
...     print("Quality issues found:")
...     for issue in issues:
...         print(f"  - {issue}")
dartwork_mpl.helpers.quality.suggest_chart_type(x_type: str, y_type: str | None, n_points: int, n_series: int = 1) str[source]

Suggest appropriate chart type based on data characteristics.

Parameters:
  • x_type (str) – Type of x data: “continuous”, “categorical”, “temporal”

  • y_type (str | None) – Type of y data: “continuous”, “categorical”, “count”, None

  • n_points (int) – Number of data points

  • n_series (int) – Number of data series

Returns:

Suggested chart type

Return type:

str

Examples

>>> chart_type = suggest_chart_type("categorical", "continuous", 5, 1)
>>> print(chart_type)  # "bar"

Example:

import dartwork_mpl as dm

# Check figure quality
issues = dm.helpers.quality.check_figure_quality(fig)
if issues:
    print("Quality issues found:")
    for issue in issues:
        print(f"  - {issue}")

# Get chart type suggestions
suggested_type = dm.helpers.quality.suggest_chart_type(
    x_data=x,
    y_data=y,
    data_type='continuous'
)
print(f"Suggested chart type: {suggested_type}")

I/O Utilities

Note

The dartwork_mpl.helpers.io submodule was retired in 0.4. The single remaining entry point for multi-format saves is dm.save_formats (canonical) — pick the file types you want and the function handles the rest.

dm.save_formats is the canonical multi-format save helper (see Save & Export for its signature).

Example:

import matplotlib.pyplot as plt
import dartwork_mpl as dm

dm.style.use("scientific")
fig, ax = plt.subplots(figsize=dm.figsize("13cm", "standard"))
ax.plot(x, y)
dm.simple_layout(fig)

# Save in multiple formats at once
dm.save_formats(fig, "output", formats=("png", "pdf", "svg"))

End-to-end Example: Automated Visualization

The helpers module composes naturally with the rest of dartwork-mpl when you want a single function to take raw data and return a finished, quality-checked figure — useful for batch reporting, automated dashboards, or letting an LLM agent produce charts without hand-tuning every call.

import dartwork_mpl as dm

def automated_visualization(data, chart_type=None):
    """Take raw ``{'x': ..., 'y': ...}`` data and return a polished figure."""

    # 1. Validate input data
    x, y = dm.helpers.data.validate_data(data["x"], data["y"])

    # 2. Suggest a chart type if not specified
    if chart_type is None:
        chart_type = dm.helpers.quality.suggest_chart_type(x, y)

    # 3. Create the figure with an appropriate style
    fig, ax = dm.helpers.io.create_figure_with_style(
        style="scientific" if chart_type == "scatter" else "web",
    )

    # 4. Pick a curated palette
    colors = dm.make_palette(
        1,
        kind="sequential" if chart_type == "line" else "categorical",
    )

    # 5. Render
    if chart_type == "line":
        ax.plot(x, y, color=colors[0])
    elif chart_type == "scatter":
        ax.scatter(x, y, color=colors[0])

    # 6. Format and quality-check
    dm.helpers.labels.format_axis_labels(ax)
    dm.helpers.labels.optimize_legend(ax)
    issues = dm.helpers.quality.check_figure_quality(fig)

    return fig, issues

See Also