lammpskit.ecellmodel.plot_atomic_distribution

lammpskit.ecellmodel.plot_atomic_distribution(file_list, labels, skip_rows, z_bins, analysis_name, output_dir=os.getcwd(), columns_to_read=None, **kwargs)[source]

Generate comprehensive atomic distribution analysis for HfTaO electrochemical devices.

Processes multiple trajectory files to compute and visualize spatial distributions of atomic species along the electrode-to-electrode axis. Provides both individual species analysis and stoichiometric composition profiling essential for understanding filament formation, material redistribution, and interface phenomena in resistive memory devices.

Parameters:
  • file_list (list of str) – List of file paths to LAMMPS trajectory files (.lammpstrj, .dump). Files should contain atomic coordinates with consistent format and time ordering. Example: [“initial_state.lammpstrj”, “final_state.lammpstrj”]

  • labels (list of str) – Descriptive labels for each trajectory file, used in plot legends and filenames. Must have same length as file_list. Example: [“Initial”, “SET”, “RESET”]

  • skip_rows (int) – Number of header rows to skip before atomic coordinate data in trajectory files. Typical LAMMPS values: 9 (standard dump format), varies with custom output.

  • z_bins (int) – Number of spatial bins for z-direction discretization. Recommended: 15-100 bins for optimal balance between resolution and statistical significance.

  • analysis_name (str) – Base name used for output file generation and plot titles. Should be descriptive of the analysis context. Example: “HfTaO_switching_analysis”

  • output_dir (str, optional) – Directory path for saving generated plots. Default: current working directory. Creates directory if it doesn’t exist.

  • columns_to_read (tuple, optional) – Column indices to read from trajectory files. If None, uses DEFAULT_COLUMNS_TO_READ from config module. Standard format: (id, type, charge, x, y, z).

  • **kwargs

    Additional keyword arguments passed to plot_multiple_cases() for plot customization:

    • yaxis: Y-axis starting position for plot alignment

    • linewidth: Line thickness for distribution curves

    • alpha: Transparency level for overlapping distributions

    • colors: Custom color scheme for different cases

    • markers: Marker styles for data points

Returns:

distribution_figures – Dictionary of matplotlib Figure objects for different analysis types:

Stoichiometric Analysis: - ‘stoichiometry’: Final-state composition (Hf_a-Ta_c-O_b stoichiometry) - ‘initial_stoichiometry’: Initial-state composition for comparison

Species-Specific Distributions: - ‘Hf’: Hafnium atom spatial distribution (conductive species) - ‘Ta’: Tantalum atom spatial distribution (matrix material) - ‘O’: Oxygen atom spatial distribution (vacancy formation species) - ‘metal’: Combined metallic species (Hf + Ta) distribution

All figures are saved to output_dir with descriptive filenames for publication use.

Return type:

dict[str, plt.Figure]

Notes

Implementation Details: The analysis implements the atom type system: - Type 2: Hf atoms - Odd types: O atoms - Even types (≠2): Ta atoms - Proportional factor 3.5: Normalization for analysis

Performance Characteristics: - Memory Usage: O(N_files × N_atoms × N_columns) for coordinate storage - Processing Speed: ~1-10s per file depending on atom count and bin resolution - Output Size: ~1-5 MB per figure depending on data complexity - Scalability: Efficient for batch processing of multiple trajectories

Integration with LAMMPSKit Ecosystem: - Data Processing: Uses calculate_atomic_distributions() for species separation - Coordinate Reading: Integrates with read_coordinates() for trajectory parsing - Visualization: Uses plot_multiple_cases() for publication-quality plotting - Validation: Employs config module functions for parameter verification

Examples

Basic device analysis workflow:

>>> from lammpskit.ecellmodel.filament_layer_analysis import plot_atomic_distribution
>>> # Compare initial vs SET state distributions
>>> trajectory_files = ["initial.lammpstrj", "set_state.lammpstrj"]
>>> case_labels = ["Initial", "SET"]
>>> figures = plot_atomic_distribution(trajectory_files, case_labels,
...                                   skip_rows=9, z_bins=50,
...                                   analysis_name="switching_analysis")
>>> print(f"Generated {len(figures)} distribution plots")

Advanced stoichiometric analysis:

>>> # Multi-state comparison with custom parameters
>>> files = ["pristine.lammpstrj", "forming.lammpstrj", "set.lammpstrj", "reset.lammpstrj"]
>>> labels = ["Pristine", "Forming", "SET", "RESET"]
>>>
>>> # High-resolution analysis with custom styling
>>> figures = plot_atomic_distribution(files, labels, skip_rows=9, z_bins=100,
...                                   analysis_name="full_cycle_analysis",
...                                   output_dir="./analysis_output",
...                                   linewidth=2.0, alpha=0.8)
>>>
>>> # Examine stoichiometric evolution
>>> stoich_fig = figures['stoichiometry']
>>> initial_stoich_fig = figures['initial_stoichiometry']
>>> print("Stoichiometric analysis completed")

Species-specific filament analysis:

>>> # Focus on conductive species evolution
>>> trajectory_files = ["before_switching.lammpstrj", "after_switching.lammpstrj"]
>>> labels = ["Before", "After"]
>>>
>>> figures = plot_atomic_distribution(trajectory_files, labels, skip_rows=9,
...                                   z_bins=75, analysis_name="filament_formation")
>>>
>>> # Analyze individual species
>>> hf_distribution = figures['Hf']      # Conductive filament species
>>> o_distribution = figures['O']        # Vacancy formation species
>>> metal_distribution = figures['metal'] # Combined metallic species
>>>
>>> print("Filament formation analysis completed")

Interface and electrode analysis:

>>> # High-resolution interface study
>>> interface_files = ["electrode_interface.lammpstrj"]
>>> interface_labels = ["Interface"]
>>>
>>> # Fine-grained binning for interface resolution
>>> figures = plot_atomic_distribution(interface_files, interface_labels,
...                                   skip_rows=9, z_bins=150,
...                                   analysis_name="interface_analysis",
...                                   yaxis=0)  # Start y-axis at zero
>>>
>>> # Examine composition near electrodes
>>> species_distributions = [figures['Hf'], figures['Ta'], figures['O']]
>>> print("Interface composition analysis completed")

Batch processing with error handling:

>>> import os
>>> # Process multiple device conditions
>>> conditions = ["low_voltage", "medium_voltage", "high_voltage"]
>>> all_figures = {}
>>>
>>> for condition in conditions:
...     try:
...         files = [f"{condition}_initial.lammpstrj", f"{condition}_final.lammpstrj"]
...         labels = ["Initial", "Final"]
...
...         if all(os.path.exists(f) for f in files):
...             figures = plot_atomic_distribution(files, labels, skip_rows=9,
...                                               z_bins=50,
...                                               analysis_name=f"{condition}_analysis")
...             all_figures[condition] = figures
...             print(f"Completed analysis for {condition}")
...         else:
...             print(f"Missing files for {condition} - skipping")
...     except Exception as e:
...         print(f"Error processing {condition}: {e}")
>>>
>>> print(f"Successfully analyzed {len(all_figures)} conditions")

Custom visualization with publication styling:

>>> # Publication-ready plots with custom styling
>>> trajectory_files = ["experimental_data.lammpstrj"]
>>> labels = ["Experimental"]
>>>
>>> # Custom styling parameters
>>> custom_kwargs = {
...     'linewidth': 3.0,
...     'alpha': 0.9,
...     'colors': ['blue', 'red', 'green'],
...     'yaxis': 0
... }
>>>
>>> figures = plot_atomic_distribution(trajectory_files, labels, skip_rows=9,
...                                   z_bins=60, analysis_name="publication_analysis",
...                                   output_dir="./publication_figures",
...                                   **custom_kwargs)
>>>
>>> print("Publication-ready figures generated")

Integration with other LAMMPSKit functions:

>>> # Combine with charge analysis for comprehensive characterization
>>> from lammpskit.ecellmodel.filament_layer_analysis import plot_atomic_charge_distribution
>>>
>>> files = ["switching_cycle.lammpstrj"]
>>> labels = ["Switching"]
>>>
>>> # Atomic distribution analysis
>>> dist_figures = plot_atomic_distribution(files, labels, skip_rows=9, z_bins=50,
...                                        analysis_name="comprehensive_analysis")
>>>
>>> # Charge distribution analysis
>>> charge_figures = plot_atomic_charge_distribution(files, labels, skip_rows=9,
...                                                 z_bins=50,
...                                                 analysis_name="comprehensive_analysis")
>>>
>>> total_figures = len(dist_figures) + len(charge_figures)
>>> print(f"Comprehensive analysis generated {total_figures} figures")