lammpskit.plotting.utils module

General-purpose plotting utilities for scientific visualization. This module provides flexible plotting functions for creating publication-ready figures across different analysis workflows with automatic styling and extensive customization options.

Design Philosophy

Functions prioritize flexibility over rigid interfaces, using **kwargs for extensive customization while maintaining consistent visual output across the LAMMPSKit ecosystem.

Core Function

plot_multiple_cases - Create multi-case comparative plots with automatic styling and layout management.

Array Dimension Support

The plot_multiple_cases() function handles multiple array configurations:

Dimension Handling

x_arr dimensions

y_arr dimensions

Usage scenario

1D

1D

Single case plot

1D

2D

Shared x-axis, multiple y-series

2D

1D

Multiple x-series, shared y-axis

2D

2D

Full multi-case plot (most common)

Customization Options

Axis Control:
  • xlimit, ylimit - Set both axis limits

  • xlimitlo, xlimithi - Set individual axis limits

  • ylimitlo, ylimithi - Set individual axis limits

Reference Lines:
  • xaxis=True - Add horizontal line at y=0

  • yaxis=True - Add vertical line at x=0

Styling:
  • markerindex - Override automatic color/marker cycling

Statistical Analysis:
  • ncount - Atom counts per bin for weighted average calculations

Usage Examples

Electrochemical cell analysis:

import numpy as np
from lammpskit.plotting import plot_multiple_cases

# Atomic distribution along z-axis (electrode-to-electrode)
z_positions = np.linspace(-10, 40, 50)
hf_distribution = np.array([[10, 15, 20], [5, 12, 18]])
labels = ['SET state', 'RESET state']

fig = plot_multiple_cases(hf_distribution, z_positions, labels,
                         'Hf atom count', 'Z position (Å)',
                         'hafnium_analysis', 10, 8)

Displacement analysis with reference lines:

displacement = np.random.normal(0, 1, 100)
positions = np.linspace(-10, 40, 100)

fig = plot_multiple_cases(displacement, positions, ['Displacement'],
                         'Displacement (Å)', 'Z position (Å)',
                         'displacement_profile', 8, 6,
                         yaxis=True, xaxis=True)  # Add reference lines

Multi-case with axis limits:

charge_data = np.array([[1, 2, 3], [2, 4, 6], [1.5, 3, 4.5]])
z_pos = np.array([0, 10, 20])
labels = ['0.5V', '1.0V', '1.5V']

fig = plot_multiple_cases(charge_data, z_pos, labels,
                         'Net charge', 'Z position (Å)', 'charge_dist', 8, 6,
                         ylimithi=70, xlimithi=25, xlimitlo=-5)

Statistical analysis with atom counts:

distributions = np.array([[10, 15, 20], [8, 12, 16]])
atom_counts = np.array([[100, 150, 200], [80, 120, 160]])  # For weighted averages

fig = plot_multiple_cases(distributions, z_positions, labels,
                         'Atom density', 'Z position (Å)', 'density', 8, 6,
                         ncount=atom_counts)  # Prints weighted averages

Output Format

Dual Format Output: All plots are automatically saved in both PDF and SVG formats:
  • {output_filename}.pdf - Vector format for publications

  • {output_filename}.svg - Web-compatible vector format

Memory Management: Figures are automatically closed after saving for memory efficiency

Performance Considerations

  • Memory usage: O(max(x_size, y_size)) per plot

  • Rendering time: O(n_cases × n_points) for line/marker rendering

  • Large datasets: Consider data downsampling for >10⁵ points

  • Batch processing: Function optimized for multiple figure generation

Common Applications

Electrochemical Analysis:
  • Atomic distributions under different voltages

  • Charge distributions across electrode separation

  • Ion migration patterns vs. position

Displacement Studies:
  • Atomic displacement profiles

  • Temperature-dependent mobility

  • Comparative displacement analysis

General MD Analysis:
  • Property distributions vs. spatial coordinates

  • Time-averaged quantities comparison

  • Multi-condition analysis workflows

Module Documentation

General-purpose plotting utilities for scientific visualization.

This module provides flexible plotting functions for creating publication-ready figures across different analysis workflows. Functions are designed for reusability with consistent styling and support for both simple and complex data visualizations.

Key Features

  • Multi-dimensional array handling for comparative analysis

  • Automatic styling with scientific color schemes and markers

  • Flexible axis control and customization options

  • Publication-ready output in multiple formats (PDF, SVG)

  • Memory-efficient plotting for large datasets

Design Philosophy

Functions prioritize flexibility over rigid interfaces, using **kwargs for extensive customization. This approach supports diverse scientific plotting needs while maintaining consistent visual output across the LAMMPSKit ecosystem.

Styling Standards

  • Color palette: [‘b’, ‘r’, ‘g’, ‘k’] (blue, red, green, black)

  • Line styles: [’–’, ‘-.’, ‘:’, ‘-’] (dashed, dash-dot, dotted, solid)

  • Markers: [‘o’, ‘^’, ‘s’, ‘*’] (circle, triangle, square, star)

  • Font sizes: 8pt labels, 7pt legends, 7pt ticks for compact publication layout

Performance Notes

Memory usage scales with data size and number of cases. For large datasets (>10^5 points), consider data downsampling before plotting. Figure generation is optimized for batch processing workflows.

Examples

Simple comparative plot:

>>> import numpy as np
>>> from lammpskit.plotting import plot_multiple_cases
>>> x = np.array([1, 2, 3])
>>> y = np.array([[1, 4, 9], [1, 8, 27]])  # Two cases as an example
>>> labels = ['Case 1', 'Case 2']
>>> fig = plot_multiple_cases(x, y, labels, 'X values', 'Y values', 'comparison', 8, 6)

Electrochemical analysis plot:

>>> z_bins = np.linspace(-10, 40, 50)  # Electrode-to-electrode z positions
>>> atom_counts = np.array([[10, 15, 20], [5, 12, 18]])  # Hf, O, Ta counts
>>> labels = ['SET state', 'RESET state']
>>> fig = plot_multiple_cases(atom_counts, z_bins, labels,
...                          'Atom count', 'Z position (Å)', 'distribution', 10, 8)
lammpskit.plotting.utils.plot_multiple_cases(x_arr, y_arr, labels, xlabel, ylabel, output_filename, xsize, ysize, output_dir=os.getcwd(), **kwargs)[source]

Create comparative plots for multiple datasets with publication-ready styling.

Versatile plotting function for scientific data visualization supporting various array dimensions and comparison scenarios. Handles both single-case and multi-case analysis with automatic styling, customizable limits, and dual-format output. Optimized for electrochemical cell analysis and general MD simulation data visualization.

Parameters:
  • x_arr (np.ndarray) – X-axis data for plotting. Supports multiple dimensions: - 1D: Single x-series for all cases - 2D: Different x-series for each case (shape: n_cases, n_points)

  • y_arr (np.ndarray) – Y-axis data for plotting. Supports multiple dimensions: - 1D: Single y-series (used with single case or shared across cases) - 2D: Different y-series for each case (shape: n_cases, n_points)

  • labels (List[str]) – Legend labels for each case. Length should match number of cases in data arrays.

  • xlabel (str) – X-axis label with units. Example: ‘Z position (Å)’, ‘Time (ps)’

  • ylabel (str) – Y-axis label with units. Example: ‘Atom count’, ‘Displacement (Å)’

  • output_filename (str) – Base filename for saved figures (extensions added automatically). Example: ‘atomic_distribution’, ‘filament_evolution’

  • xsize (float) – Figure width in inches. Note: Function overrides with hardcoded value (1.6).

  • ysize (float) – Figure height in inches. Note: Function overrides with hardcoded value (3.2).

  • output_dir (str, optional) – Output directory for saved figures. Created if doesn’t exist (default: cwd).

  • **kwargs (dict, optional) –

    Advanced customization options:

    Axis Limits:

    xlimit : tuple (xmin, xmax) - Set both x-axis limits ylimit : tuple (ymin, ymax) - Set both y-axis limits xlimitlo : float - Set x-axis lower limit only xlimithi : float - Set x-axis upper limit only ylimitlo : float - Set y-axis lower limit only ylimithi : float - Set y-axis upper limit only

    Reference Lines:

    xaxis : bool - Add horizontal line at y=0 yaxis : bool - Add vertical line at x=0

    Styling:

    markerindex : int - Override automatic color/marker cycling

    Statistical Analysis:
    ncountnp.ndarray - Atom counts per bin for average calculations

    Shape: (n_cases, n_bins). Prints weighted averages.

Returns:

fig – Figure object for further customization or display. Note: Figure is automatically saved and closed for memory efficiency.

Return type:

matplotlib.figure.Figure

Notes

Array Dimension Handling: - x_arr.ndim=1, y_arr.ndim=1: Single case plot - x_arr.ndim=1, y_arr.ndim=2: Shared x-axis, multiple y-series - x_arr.ndim=2, y_arr.ndim=1: Multiple x-series, shared y-axis - x_arr.ndim=2, y_arr.ndim=2: Full multi-case plot (most common)

Performance Characteristics: - Memory usage: O(max(x_size, y_size)) - Rendering time: O(n_cases * n_points) - File I/O: Dual output (PDF + SVG) for versatility

Output Format: - PDF: Vector format for publications and presentations - SVG: Web-compatible vector format for interactive displays - Both saved with tight bounding boxes for clean appearance

Common Usage Patterns in LAMMPSKit:

Electrochemical analysis (atom distributions): >>> plot_multiple_cases(distributions[‘hafnium’], z_bin_centers, labels, … ‘Hf atoms #’, ‘z position (A)’, ‘hf_distribution’, 8, 6)

Displacement analysis: >>> plot_multiple_cases(zdisp, binposition, labels, … ‘z displacement (A)’, ‘z position (A)’, ‘z_disp’, 8, 6, … yaxis=True) # Add y=0 reference line

Charge distribution with axis limits: >>> plot_multiple_cases(charge_data, z_positions, labels, … ‘Net charge’, ‘z position (A)’, ‘charge_dist’, 8, 6, … ylimithi=70, xlimithi=15, xlimitlo=-20)

Examples

Basic multi-case comparison:

>>> import numpy as np
>>> z_pos = np.linspace(0, 30, 50)  # Electrode positions
>>> hf_counts = np.array([[5, 10, 15], [8, 12, 18]])  # Two voltage states
>>> labels = ['0.5V', '1.0V']
>>> fig = plot_multiple_cases(hf_counts, z_pos, labels,
...                          'Hf atom count', 'Z position (Å)',
...                          'hafnium_analysis', 10, 8)

Single case with reference lines:

>>> displacement = np.random.normal(0, 1, 100)
>>> positions = np.linspace(-10, 40, 100)
>>> fig = plot_multiple_cases(displacement, positions, ['Displacement'],
...                          'Displacement (Å)', 'Z position (Å)',
...                          'displacement_profile', 8, 6,
...                          yaxis=True, xaxis=True)

Multi-dimensional array example:

>>> # 3 cases, 4 elements each
>>> element_counts = np.random.randint(1, 20, (3, 4))
>>> elements = ['Hf', 'Ta', 'O', 'Electrode']
>>> case_labels = ['SET', 'Intermediate', 'RESET']
>>> fig = plot_multiple_cases(element_counts, elements, case_labels,
...                          'Element count', 'Element type',
...                          'element_comparison', 12, 8)