pymatviz: Toolkit for Visualizations in Materials Informatics

repository·main·Indexed 43 days ago

https://github.com/janosh/pymatviz

A toolkit for materials informatics providing specialized visualizations including periodic table heatmaps, phonon spectra, and composition clustering. Version 0.18.0 features tools for 3D Brillouin zone rendering, XRD patterns, radial distribution functions, and interactive widgets for structures and trajectories via MatterViz. It supports dimensionality reduction (PCA, t-SNE, UMAP) for chemical compositions and offers various plot types such as sunbursts, treemaps, raincloud plots, and Sankey diagrams.

Tokens
24.7K
Snippets
88
Records
105
Agent score
55%

What's inside pymatviz

  1. Overview of material property datasets used in pymatviz examples

    main

    The pymatviz examples directory primarily utilizes datasets from the MatBench collection for exploratory data analysis. Other significant datasets included in the examples are:

    • Electronic Transport Properties (Ricci carrier transport): Contains 48,000 DFT Seebeck coefficients.
    • boltztrap_mp: Contains ~9,000 effective mass and thermoelectric properties calculated via BoltzTraP.
    • tri_camd_2022: Toyota Research Institute's 2nd active learning crystal discovery dataset.
    • WBM: A dataset for predicting stable crystalline compounds using chemical similarity.
  2. Composition Clustering with cluster_compositions

    main

    Visualize 2D or 3D relationships between chemical compositions and properties using various embedding and dimensionality reduction techniques.

    Embedding Methods

    • one-hot: One-hot encoding of element fractions.
    • magpie: Magpie features (elemental properties).
    • matscholar_el: Matscholar element embeddings.
    • megnet_el: MEGNet element embeddings

    Dimensionality Reduction (Projection) Methods

    • pca: Principal Component Analysis (linear).
    • tsne: t-SNE (non-linear).
    • umap: UMAP (non-linear).
    • isomap: Isomap (non-linear).
    • kernel_pca: Kernel PCA (non-linear).
  3. Use Interactive Widgets for 3D structures, compositions, and trajectories

    main

    Pymatviz provides interactive widgets for Jupyter, Marimo, and VSCode notebooks using anywidget and MatterViz. These widgets allow for interactive 3D visualization of structures, composition analysis, and molecular dynamics trajectories.

    Supported objects:

    • Structures: pymatgen Structure, ASE Atoms, and PhonopyAtoms.
    • Trajectories: ASE, pymatgen, and plain Python formats.

    Widget constructors mirror the props of the underlying MatterViz components. All plot widgets include control pane options: show_controls, controls_open, controls_toggle_props, and controls_pane_props.

    from pymatviz import StructureWidget, CompositionWidget, TrajectoryWidget
    from pymatgen.core import Structure, Composition
    
    # Interactive 3D structure visualization
    structure = Structure.from_file("structure.cif")
    struct_widget = StructureWidget(structure=structure)
    
    # Interactive composition visualization
    composition = Composition("Fe2O3")
    comp_widget = CompositionWidget(composition=composition)
    
    # Interactive trajectory visualization
    # Option 1: List of structures
    trajectory1 = [struct1, struct2, struct3]
    traj_widget1 = TrajectoryWidget(trajectory=trajectory1)
    
    # Option 2: List of dicts with structure and properties
    trajectory2 = [
        {"structure": struct1, "energy": 1.0}, 
        {"structure": struct2, "energy": 2.0}, 
        {"structure": struct3, "energy": 3.0}
    ]
    traj_widget2 = TrajectoryWidget(trajectory=trajectory2)
  4. Export and inspect widgets in headless environments

    main

    All widgets support APIs for exporting to files or inspecting data, which is useful for plain Python scripts, CI/CD, or agent workflows where a notebook frontend is unavailable.

    Requirements: to_img and render_report require Playwright. Install via: pip install pymatviz[export] && playwright install chromium.

    Environment Variable: Set PYMATVIZ_STATIC to make widget.show() render static PNGs instead of live interactive widgets (useful for CI notebook execution).

    widget.to_html("structure.html")  # standalone interactive HTML page
    widget.to_img("structure.png", dpi=150)  # PNG/JPEG/SVG/PDF via headless Chromium
    widget.describe()  # machine-readable facts: counts, ranges, formula, chemical system
    widget.render_report()  # headless render health check: blank fraction, warnings
  5. Configure hover data in `rainclouds()`

    main

    You can enrich the tooltips in a raincloud plot using the hover_data parameter. This is particularly useful when your data is provided as a (pd.DataFrame, column_name) tuple.

    Supported Formats for hover_data

    1. List of strings: If using a DataFrame, pass a list of column names to include in the hover text for all datasets.
      • Example: hover_data=["temperature", "pressure"]
    2. Mapping (Dictionary): Provide specific hover columns for specific labels.
      • Nested Mapping: {"label_name": {"column_name": [values]}} (used for custom per-point arrays).
      • Simple Mapping: {"label_name": ["col1", "col2"]} (used to pick columns from a DataFrame associated with that label).

    Note: If a column is the primary data column being plotted, it is automatically included and will not be duplicated in the hover text.

    # If data is: {"train": (df, "val_col")}
    # And df has columns ['val_col', 'temp', 'source']
    
    # To show 'temp' and 'source' in tooltips:
    fig = rainclouds(data, hover_data=["temp", "source"])
    
    # Or to be label-specific:
    fig = rainclouds(data, hover_data={"train": ["temp"]})
  6. Access pymatviz crystal system order

    main

    When creating plots that involve crystal systems, pymatviz defines a standard order for categorical axes to ensure consistent visualization across different plots:

    cubic $\rightarrow$ hexagonal $\rightarrow$ trigonal $\rightarrow$ tetragonal $\rightarrow$ orthorhombic $\rightarrow$ monoclinic $\rightarrow$ triclinic.

  7. Use element-based color schemes

    main

    The module provides several pre-defined color schemes for mapping chemical elements (using their symbols, e.g., 'H', 'Fe', 'Au') to colors. These schemes are available in two formats:

    1. 256-scale (RGB 0-255): Useful for direct color manipulation or saving to formats requiring integer RGB.
    2. Matplotlib-scale (RGB 0-1): Normalized floats, ready for direct use in matplotlib functions.

    Available schemes include:

    • ELEM_COLORS_JMOL: Based on Jmol color conventions.
    • ELEM_COLORS_VESTA: Based on VESTA color conventions.
    • ELEM_COLORS_ALLOY: A high-contrast scheme optimized for metal alloys.
    • ELEM_COLORS_PASTEL: A pastel color scheme designed for high contrast between elements.
  8. Importing pymatviz

    main

    Importing pymatviz applies sensible global defaults for Plotly, such as increasing font sizes and improving axis labels with sub/superscripts. It also automatically enables notebook_mode if running in an IPython environment.

    Note that importing the package has side-effects on the global plotly.express configuration.

    import pymatviz
  9. Create an interactive Dash app with ptable_heatmap

    main

    You can wrap pymatviz figures in a Dash application to create interactive dashboards. This allows users to switch between different views (like different compound arities) using components like dash.dcc.Dropdown.

    import dash
    from dash import dcc, html
    from dash.dependencies import Input, Output
    import plotly.graph_objects as go
    import pymatviz as pmv
    
    # 1. Prepare your figures
    arity_figs = {
        "unary": pmv.ptable_heatmap(unary_counts),
        "binary": pmv.ptable_heatmap(binary_counts)
    }
    
    # 2. Setup Dash app
    app = dash.Dash(prevent_initial_callbacks=True)
    
    graph = dcc.Graph(figure=arity_figs["unary"], id="ptable-heatmap", responsive=True)
    dropdown = dcc.Dropdown(
        id="arity-dropdown",
        options=[{"label": k, "value": k} for k in arity_figs.keys()],
        value="unary"
    )
    
    app.layout = html.Div([graph, dropdown])
    
    # 3. Define callback to update figure
    @app.callback(Output(graph.id, "figure"), Input(dropdown.id, "value"))
    def update_figure(dropdown_value):
        return arity_figs[dropdown_value]
    
    app.run(debug=True, mode="inline")