Skip to content

Plotting

The shared plotting machinery. Figure loading and saving, legend and marker post-processing, and the plotly templates all live here in one copy — cellpy.utils.plotutils and cellpy.utils.collectors re-export from it, so existing imports keep working. Batch.plot delegates to cellpy.plotting.batch_summary_plot (#658); the old cellpy.utils.batch_tools.batch_plotters module is gone.

The drawing functions themselves (summary_plot, raw_plot, cycle_info_plot, cycles_plot) still live in Utils and move here in a later phase of the redesign.

figures

Loading and saving figures — one implementation (#567).

load_figure, load_plotly_figure, load_matplotlib_figure, save_matplotlib_figure and make_matplotlib_manager existed as full copies in both utils/plotutils.py and utils/collectors.py.

Four of the five pairs were character-identical. The fifth was not, and the difference mattered: plotutils' load_plotly_figure checks whether plotly is installed and returns None if it is not, while collectors' copy went straight to pio.read_json and raised NameError/ImportError on an install without the batch extra. The guarded behaviour is the one kept here, so the degradation is the same wherever you call it from.

load_figure

load_figure(filename, backend=None)

Load a figure saved by cellpy.

Parameters:

  • filename

    the file to read.

  • backend

    "plotly", "matplotlib" or "seaborn" (an alias for matplotlib). Inferred from the suffix when not given.

Returns:

  • The figure, or None if it could not be loaded.

load_matplotlib_figure

load_matplotlib_figure(filename, create_new_manager=False)

Unpickle a matplotlib figure.

Parameters:

  • filename

    the pickle written by save_matplotlib_figure.

  • create_new_manager

    attach a canvas manager so the figure can be shown.

load_plotly_figure

load_plotly_figure(filename)

Read a plotly figure from JSON.

Returns None — rather than raising — when plotly is not installed or the file cannot be read, which is what the plotutils copy always did.

make_matplotlib_manager

make_matplotlib_manager(fig)

Attach a fresh canvas manager to an unpickled figure.

An unpickled figure has no manager, so it cannot be shown. Borrowing one from a throwaway figure is the standard workaround (https://stackoverflow.com/a/54579616/8508004).

save_matplotlib_figure

save_matplotlib_figure(fig, filename)

Pickle a matplotlib figure to filename.

labels

Legend, marker, and axis-label helpers for plotting (#567 / #647).

Legend/marker helpers existed in three places, under two naming conventions (plotutils / collectors / the retired batch_plotters). The marker helpers were functionally identical; the batch_plotters legend copy carried an extra inverted_mode that swaps group and sub-group. That copy is the one kept — with inverted_mode=False as the default.

Axis labels for raw_plot / cycle_info_plot go through :func:quantity_label / :func:units_quantity_label so those paths do not hand-compose f"{name} ({unit})" strings (#647).

legend_replacer

legend_replacer(trace, df, group_legends=True, inverted_mode=False)

Replace a "group,subgroup" legend label with the cell name.

Plotly names a trace after the columns it was grouped by, so a batch figure ends up with legends like "2,1". This looks the pair up in the journal and substitutes the cell name, in the legend and in the hover text.

Parameters:

  • trace

    the plotly trace to update, in place.

  • df

    journal frame carrying group / sub-group / cell columns.

  • group_legends

    put every sub-group of a group in one legend entry.

  • inverted_mode

    the label reads "subgroup,group" rather than "group,subgroup".

Returns:

  • The trace, updated.

quantity_label

quantity_label(name: str, unit: str) -> str

Compose an axis label name (unit).

Parameters:

  • name (str) –

    human-readable quantity name, e.g. "Voltage".

  • unit (str) –

    unit string already resolved for the plotted series.

Returns:

  • str

    e.g. "Voltage (V)", "Time (hours)".

remove_markers

remove_markers(trace)

Turn a plotly trace into a plain line.

units_quantity_label

units_quantity_label(name: str, physical_property: str, mode: Optional[str] = None, *, units: Optional['CellpyUnits'] = None) -> str

Axis label via :func:cellpy.units.units_label.

Parameters:

  • name (str) –

    human-readable quantity name.

  • physical_property (str) –

    as :func:~cellpy.units.units_label.

  • mode (Optional[str], default: None ) –

    as :func:~cellpy.units.units_label.

  • units (Optional['CellpyUnits'], default: None ) –

    unit spec for the series (e.g. cell.data.raw_units).

Returns:

  • str

    e.g. "Voltage (V)", "Charge capacity (Ah)".

theme

Plotly templates — one implementation (#567).

_make_plotly_template existed in both utils/plotutils.py and the retired utils/batch_tools/batch_plotters.py. The bodies were identical; the only difference was that plotutils' copy checked whether plotly was installed first, which is the behaviour kept here.

Building a template registers it with plotly under name, so the two copies were also silently competing for the same registry key: whichever module was imported last won. There is now one definition and one registration.

make_collector_templates

make_collector_templates(register: bool = True) -> dict | None

Build (and by default register) the collector template family.

Built lazily on purpose. These used to be four module-level go.layout.Template(...) calls in collectors.py, which made import cellpy.utils.collectors raise NameError: name 'go' is not defined on any install without the batch extra — the module was simply unimportable without plotly.

Parameters:

  • register (bool, default: True ) –

    also put them in plotly.io.templates.

Returns:

  • dict | None

    {name: template}, or None when plotly is not installed.

make_plotly_template

make_plotly_template(name: str = 'axis')

Build the cellpy axis template and register it with plotly.

Parameters:

  • name (str, default: 'axis' ) –

    the key to register under in plotly.io.templates.

Returns:

  • The template, or None when plotly is not installed.

batch_summary

Batch cycle-life summary plots (#658).

Relocated from cellpy.utils.batch_tools.batch_plotters so Batch.plot delegates into cellpy.plotting. Public backends: plotly (primary) and matplotlib. seaborn is a deprecated alias for matplotlib; bokeh raises.

batch_summary_plot

batch_summary_plot(experiment: Any, *, backend: Optional[str] = None, show: Optional[bool] = None, **kwargs: Any) -> Any

Draw the Batch cycle-life summary figure (cap / CE / IR / rate panels).

Parameters:

  • experiment (Any) –

    CyclingExperiment with memory_dumped["summary_engine"].

  • backend (Optional[str], default: None ) –

    plotly or matplotlib (after triage).

  • show (Optional[bool], default: None ) –

    if True, call figure.show() for plotly (default True for plotly).

  • **kwargs (Any, default: {} ) –

    forwarded to frame prep / renderers (capacity_specifics, ce_range, ir, rate, filters, …).

Returns:

  • Any

    Backend-native figure/canvas, or None if prep/render fails.

create_legend

create_legend(info, c, option='clean', use_index=False)

creating more informative legends

create_plot_option_dicts

create_plot_option_dicts(info, marker_types=None, colors=None, line_dash=None, size=None, palette=None)

Create two dictionaries with plot-options.

The first iterates colors (based on group-number), the second iterates through marker types.

Returns: group_styles (dict), sub_group_styles (dict)

plot_cycle_life_summary_plotly

plot_cycle_life_summary_plotly(summaries: DataFrame, **kwargs)

Plotting cycle life summaries using plotly.

resolve_batch_plot_backend

resolve_batch_plot_backend(backend: Optional[str]) -> str

Normalize Batch.plot backend names (triage for #658).