Skip to content

Polyhedron & Ring Highlight

Two visualization features for structural analysis:

  • Polyhedron — render coordination polyhedra around atoms in solid-state structures
  • Ring Highlight — fill aromatic and aliphatic rings in molecules with a semi-transparent color

See the MolecularViewer API reference for the full parameter list.


Polyhedron Visualization

Live Demo: CaSiO₃ (Tetragonal Perovskite)

SiO₄ tetrahedra and CaO₈ polyhedra in CaSiO₃ (2×2×2 supercell, space group I4/mcm):


How It Works

For each atom with coordination number (CN) ≥ 4 that is also a valid polyhedron center, a convex hull polyhedron is drawn around its bonded neighbors. Following VESTA and Crystal Toolkit practice, a center must be strictly more cation-like (lower electronegativity) than every vertex, so rock salt draws only Na-centred octahedra instead of interpenetrating Na and Cl shells. By default, each face uses the average active element color of its three corner atoms. The color can instead follow the center element, one explicitly selected color, a coordination-number palette, or an angle-classified coordination geometry.

The bond detection uses scaled covalent radii (controlled by bondThreshold); the polyhedra follow exactly the same neighbor list. For periodic structures, aseview calculates the base-cell bond topology with integer image shifts and then copies it. Completion atoms beyond the selected cells are hidden by default; enable One-hop bonded atoms (showOneHopBondedAtoms=True, or the legacy showPeriodicImages=True) when complete boundary-spanning coordination shells should be visible. A bare unit cell usually shows no polyhedra at all, because the coordinating neighbours sit outside it. Cells selected with Add Periodicity still connect directly to one another.

Optionally, thin edge lines (THREE.EdgesGeometry) can be overlaid on each face to make the geometry more legible.

Code Example

from ase.build import bulk
from aseview import MolecularViewer

# NaCl rocksalt — Na & Cl are octahedrally coordinated (CN=6)
atoms = bulk("NaCl", "rocksalt", a=5.64) * (2, 2, 2)

viewer = MolecularViewer(
    atoms,
    showPolyhedron=True,       # enable polyhedra
    polyhedronColorMode="geometry",
    polyhedronGeometryColors={
        "tetrahedral": "#3b82f6",
        "squarePlanar": "#06b6d4",
        "trigonalBipyramidal": "#8b5cf6",
        "squarePyramidal": "#a855f7",
        "pentagonalPlanar": "#10b981",
        "octahedral": "#f59e0b",
        "pentagonalBipyramidal": "#ef4444",
        "other": "#64748b",
    },
    polyhedronOpacity=0.25,    # face transparency 0.0–1.0
    showPolyhedronEdge=True,   # dark wireframe edges
    polyhedronEdgeOpacity=0.7, # edge visibility 0.0–1.0
)
viewer.show()
from ase.io import read
from aseview import MolecularViewer

atoms = read("structure.cif") * (2, 2, 2)

viewer = MolecularViewer(
    atoms,
    style="default",
    showCell=True,
    showPolyhedron=True,
    polyhedronOpacity=0.25,
    bondThreshold=1.1,
)
viewer.show()

Parameters

Parameter Type Default Description
showPolyhedron bool False Enable polyhedron rendering
polyhedronOpacity float 0.25 Face transparency (0 = invisible, 1 = solid)
polyhedronColorMode str "neighbor" "neighbor", "center", "uniform", "coordination", or "geometry"
polyhedronColor str "#4f8cff" Explicit face color used by "uniform" mode
polyhedronColors dict CN palette Colors keyed by "4", "5", "6", "7", and "other"
polyhedronGeometryColors dict Geometry palette Colors keyed by supported geometry names and "other"
polyhedronPairs list[dict] [] Optional center/neighbor element filters such as {"center": "Si", "neighbor": "O"}
showPolyhedronEdge bool True Show wireframe edge lines on each face
polyhedronEdgeOpacity float 0.70 Edge line opacity (0 = invisible, 1 = opaque)

Coordination threshold

Only atoms with CN ≥ 4 generate polyhedra. Atoms with fewer bonds (e.g., terminal O in a chain) are skipped.

Coordination color is not shape recognition

The "coordination" mode colors only by the number of selected neighbors. Use "geometry" to compare the shell's sorted pairwise bond angles against supported ideal geometries. Fits above 18° RMS and unsupported coordination numbers deliberately use the "other" color; this is a discrete angle-fingerprint classifier, not a full continuous-shape-measure analysis.

Edge line width

WebGL does not support linewidth > 1. Edges are always 1 px wide; adjust polyhedronEdgeOpacity to make them more or less prominent.

UI Controls

When Polyhedron is toggled ON in Display Settings, the following controls appear:

Control Description
Polyhedron Opacity slider Adjust face transparency
Polyhedron Color selector Choose neighbor-face, center-element, single-color, coordination-number, or coordination-geometry coloring
Single Color picker Set an exact color for all polyhedra
Coordination Palette pickers Set separate CN 4, 5, 6, 7, and fallback colors
Geometry Palette pickers Set colors for tetrahedral, square-planar, trigonal-bipyramidal, square-pyramidal, pentagonal-planar, octahedral, pentagonal-bipyramidal, and other shells
Polyhedron Edge toggle Show / hide wireframe edges
Edge Opacity slider Adjust edge line visibility
Polyhedron Pairs chips Select center and neighbor elements used to construct polyhedra

Ring Highlight

Live Demo: Carbazole

Tricyclic aromatic system: two benzene rings fused to a pyrrole ring (C₁₂H₉N core):


How It Works

A BFS-based ring detection algorithm finds all smallest rings of 4–8 atoms in the molecular bond graph. For each ring, a fan-triangulated face is drawn using the CPK color of the most common element in that ring.

Code Example

from ase.build import molecule
from aseview import MolecularViewer

benzene = molecule("C6H6")

viewer = MolecularViewer(
    benzene,
    showRings=True,
    ringOpacity=0.4,
)
viewer.show()
from ase.build import molecule
from aseview import MolecularViewer

naphthalene = molecule("C10H8")

viewer = MolecularViewer(
    naphthalene,
    style="cartoon",
    showRings=True,
    ringOpacity=0.4,
)
viewer.show()
from ase.io import read
from aseview import MolecularViewer

atoms = read("carbazole.xyz")

viewer = MolecularViewer(
    atoms,
    style="cartoon",
    showRings=True,
    ringOpacity=0.35,
    bondThreshold=1.15,
)
viewer.show()

Parameters

Parameter Type Default Description
showRings bool False Enable ring face rendering
ringOpacity float 0.30 Face transparency (0 = invisible, 1 = solid)

Ring size range

Rings of 4–8 atoms are detected. Larger macrocycles (crown ethers, porphyrins > 8 atoms) are not highlighted.

UI Controls

In the sidebar → Display Settings:

  • Ring Highlight toggle — show/hide ring faces
  • Ring Opacity slider — adjust transparency in real time

Combining Both Features

Both features can be enabled simultaneously:

from ase.io import read
from aseview import MolecularViewer

atoms = read("your_structure.cif")

viewer = MolecularViewer(
    atoms,
    showPolyhedron=True,
    polyhedronOpacity=0.2,
    showPolyhedronEdge=True,
    polyhedronEdgeOpacity=0.7,
    showRings=True,
    ringOpacity=0.35,
    showCell=True,
)
viewer.show()