A molecular viewer for ASE (Atomic Simulation Environment) data
Project description
aseview
Molecular structure viewer for ASE (Atomic Simulation Environment).
Features
- Interactive structure, trajectory, overlay, normal-mode, and fragment-selection viewers
- ASE-backed Python API and CLI, plus a browser-only JavaScript module
- Cell/PBC display, bonds, hydrogen bonds, charges, magnetic moments, forces, and fixed-atom constraint highlighting
- Energy and max-force (Fmax) trajectory plots with independent force-plot toggling
- Radius Contrast control for reducing or restoring element-radius size differences
- Visual styles including cartoon, glossy, metallic, cinematic, bubble, neon, grey, and 2D
- Hide hydrogens without deleting data, and apply optional render blur to saved images
- Clipboard export for current frame or full trajectory as
xyz,extxyz,cif, orPOSCAR - Cell-aware camera presets and browser PNG/GIF export for rendered viewers
Installation
Recommended:
uv venv -p 3.11
uv pip install aseview
uv run aseview -h
pip install aseview
For Python PNG/GIF export:
pip install "aseview[export]"
python -m playwright install chromium
For development:
git clone https://github.com/kangmg/aseview.git
cd aseview
pip install -e .
CLI Usage
# Basic usage
aseview molecule.xyz
# View trajectory (all frames)
aseview trajectory.xyz -i :
# View specific frames
aseview trajectory.xyz -i 0:10 # frames 0-9
aseview trajectory.xyz -i -1 # last frame
aseview trajectory.xyz -i ::2 # every 2nd frame
# Specify file format
aseview POSCAR -f vasp
# Custom port
aseview molecule.xyz -p 9000
# Overlay multiple structures
aseview reactant.xyz product.xyz
# Overlay with colormap
aseview trajectory.xyz -v overlay --cmap viridis
# Normal mode visualization with ORCA Hessian or VASP OUTCAR
aseview molecule.xyz --hess orca.hess
aseview POSCAR --hess OUTCAR
# Save as HTML file
aseview molecule.xyz -o output.html
# Choose a visual theme
aseview molecule.xyz --theme spring
aseview molecule.xyz -t glass -o out.html
# Kill existing server on port
aseview molecule.xyz -k
# Help
aseview -h
SSH Port Forwarding
When running on a remote server (e.g., HPC cluster, Docker container):
# 1. On remote server
aseview molecule.xyz -p 8080
# 2. On local machine (separate terminal)
ssh -L 8080:localhost:8080 user@remote-server
# 3. Open in local browser
# http://localhost:8080
For Docker with custom SSH port:
# Connect with port forwarding
ssh user@localhost -p 10011 -L 8080:localhost:8080
# Then run aseview inside container
aseview molecule.xyz -p 8080
Jupyter Notebook
Quick Start
from ase.io import read
from aseview import MolecularViewer
atoms = read('molecule.xyz')
viewer = MolecularViewer(atoms)
viewer.show()
With Trajectory
from ase.io import read
from aseview import MolecularViewer
# Read all frames
trajectory = read('trajectory.xyz', index=':')
viewer = MolecularViewer(trajectory)
viewer.show()
Overlay Multiple Structures
from ase.io import read
from aseview import OverlayViewer
reactant = read('reactant.xyz')
product = read('product.xyz')
viewer = OverlayViewer([reactant, product])
viewer.show()
Overlay with Colormap
from ase.io import read
from aseview import OverlayViewer
trajectory = read('optimization.xyz', index=':')
viewer = OverlayViewer(
trajectory,
colorBy='Colormap',
colormap='viridis' # viridis, plasma, coolwarm, jet, rainbow, grayscale
)
viewer.show()
For long overlays, only the first three structures are visible by default. Use
all_visible=True to start with every structure visible, or
visible_indices=[...] to choose the initially visible structures:
viewer = OverlayViewer(trajectory, all_visible=True)
viewer = OverlayViewer(trajectory, visible_indices=[0, len(trajectory) - 1])
Normal Mode Visualization
From ASE Vibrations
from ase import Atoms
from ase.calculators.emt import EMT
from ase.optimize import BFGS
from ase.vibrations import Vibrations
from aseview import NormalViewer
# Create or load molecule
atoms = Atoms('H2O', positions=[[0, 0, 0], [0.96, 0, 0], [-0.24, 0.93, 0]])
atoms.calc = EMT()
# Optimize structure
opt = BFGS(atoms)
opt.run(fmax=0.01)
# Calculate vibrations
vib = Vibrations(atoms, name='vib')
vib.run()
vib.summary()
# Visualize normal modes
viewer = NormalViewer(atoms, vibrations=vib)
viewer.show()
From ORCA Hessian File
from ase.io import read
from aseview import NormalViewer
atoms = read('molecule.xyz')
viewer = NormalViewer.from_orca(atoms, 'orca.hess')
viewer.show()
From VASP OUTCAR
from ase.io import read
from aseview import NormalViewer
atoms = read('POSCAR')
viewer = NormalViewer.from_vasp(atoms, 'OUTCAR')
viewer.show()
Features:
- Mode selector dropdown with frequencies
- Sinusoidal animation of atomic displacements
- Amplitude slider to control displacement magnitude
- Show Vectors toggle to display mode displacement arrows
- Imaginary frequencies (transition states) shown in red
Using view_molecule Helper
from aseview.jupyter import view_molecule
from ase.io import read
atoms = read('molecule.xyz')
view_molecule(atoms, viewer_type='molecular', height=600)
Lightweight Viewer (PyMOL-style)
from aseview import view
# Single structure
view(atoms)
# Trajectory/list of ASE Atoms with CSS play button + frame slider
viewer = view(traj, styles='cinematic', fps=24, hide_hs=True, center=True, width=400, height=400)
# view() returns LiteViewer, so the same object can be saved as HTML
viewer.save_html('lite_view.html')
Custom Settings
from aseview import MolecularViewer
viewer = MolecularViewer(
atoms,
style='neon', # default, cartoon, neon, glossy, metallic, cinematic, rowan, grey
bondThreshold=1.2, # bond detection scale factor
atomSize=0.5,
radiusContrast=0.8, # 0.0 = uniform radii, 1.0 = element radii
radiusContrastMode='log', # log or linear interpolation
showCell=False,
backgroundColor='#000000',
showEnergyPlot=True,
showForceMaxPlot=True,
showConstraint=True, # highlight FixAtoms constraints
showPolyhedron=True, # coordination polyhedra (solid-state, CN >= 4)
polyhedronOpacity=0.25,
showRings=True, # ring face highlighting (molecules, 4-8 atom rings)
ringOpacity=0.35,
viewPreset='top-c', # top-c/c/top, bottom-c, side-a/a, side-b/b, front/back/left/right
viewFit=1.1, # camera fit multiplier
)
viewer.show(width='100%', height=800)
Camera settings accepted by MolecularViewer, OverlayViewer, and
NormalViewer are viewPreset, viewDirection, viewEuler, viewUp, and
viewFit. Presets top-c, bottom-c, side-a, and side-b use valid unit
cell vectors; c is an alias for top-c, a for side-a, and b for
side-b. The top preset also prefers the cell c axis when a valid cell is
present. Missing, non-periodic, zero-length, or degenerate cells fall back to
Cartesian top, bottom, front, back, left, and right directions.
Save to HTML
viewer.save_html('output.html')
Fragment Selector (Interactive Atom Selection)
from ase.build import molecule
from aseview import FragSelector
atoms = molecule('CH3OH') # or read('molecule.xyz')
FragSelector(atoms).show()
The Fragment Selector shows a synchronized 2D + 3D view for picking atom subsets. Selected atoms are highlighted in yellow in both panels.
Interaction modes (keyboard shortcuts: N / C / R / L):
| Mode | How to activate | 2D action |
|---|---|---|
| Navigate | N key | drag to pan, scroll to zoom |
| Click | C key | click individual atoms to toggle |
| Rect | R key | drag a rectangle to select atoms |
| Lasso | L key | draw a freeform region to select atoms |
Hold Shift while releasing to add to the existing selection instead of replacing it.
# Save selected indices after interactive picking:
viewer = FragSelector(atoms, bondThreshold=1.2, style='cartoon')
viewer.save_html('selector.html')
# CLI usage (opens in browser):
# aseview molecule.xyz -v frag
Viewer Types
| Viewer | Description |
|---|---|
| MolecularViewer | Single structure or trajectory animation |
LiteViewer / view(...) |
Minimal render-only viewer with optional play/stop |
| NormalViewer | Normal mode vibration visualization |
| OverlayViewer | Compare multiple structures overlaid |
| FragSelector | Interactive 2D+3D atom selection with rect/lasso |
VS Code Extension
The vscode-extension/ package provides a native VS Code custom editor for structure files. It uses ase-ts for parsing and writing, so it does not require a Python runtime inside VS Code.
Supported default file patterns include *.xyz, *.extxyz, *.cif, *.pdb, *.vasp, POSCAR, and CONTCAR.
cd vscode-extension
npm install
npm run compile
npm run package
Install the generated .vsix from VS Code with Extensions -> Install from VSIX....
On GitHub releases, the VS Code workflow builds the same package and attaches aseview.vsix to the release assets.
Themes
aseview ships with multiple visual themes. Each theme is a complete HTML template set that controls the viewer's colour scheme, background, and UI style.
| Theme | Description |
|---|---|
dark |
Default dark theme with deep grey background |
darkgreen |
Dark theme with green accent colours |
simple |
Minimal, low-distraction theme |
spring |
Light pastel theme with bright, airy colours |
glass |
Frosted-glass aesthetic with translucent UI panels |
CLI
aseview molecule.xyz --theme spring
aseview molecule.xyz -t glass -o out.html
Python API
import aseview
# Per-viewer
viewer = aseview.MolecularViewer(atoms, theme='spring')
viewer = aseview.OverlayViewer([a, b], theme='glass')
viewer = aseview.NormalViewer(atoms, theme='dark')
viewer = aseview.FragSelector(atoms, theme='spring')
# Global — all subsequent viewers use this theme
aseview.set_theme('spring')
viewer1 = aseview.MolecularViewer(atoms) # spring
viewer2 = aseview.FragSelector(atoms) # spring
# Inspect
aseview.list_themes() # ['dark', 'darkgreen', 'glass', 'simple', 'spring']
aseview.get_theme() # current default
JavaScript Module
// Per-viewer
const v = new ASEView.MolecularViewer('#container', { theme: 'spring' });
// Global
ASEView.setTheme('glass');
const v2 = new ASEView.OverlayViewer('#container'); // glass
See the Theming guide for instructions on creating custom themes.
JavaScript Module
Use aseview in any web page without Python:
<div id="viewer" style="width:100%; height:500px;"></div>
<script src="https://cdn.jsdelivr.net/gh/kangmg/aseview@main/aseview/static/js/aseview.js"></script>
<script>
const viewer = new ASEView.MolecularViewer('#viewer', { viewPreset: 'top-c' });
viewer.setData({
symbols: ['O', 'H', 'H'],
positions: [
[0.0, 0.0, 0.117],
[0.0, 0.757, -0.469],
[0.0, -0.757, -0.469]
]
});
viewer.setView({ preset: 'front' }).then(() => {
return viewer.savePNG({ returnDataUrl: true, download: false });
}).then((png) => {
console.log(png.filename, png.dataUrl.length);
});
</script>
See the JavaScript Module documentation for full API reference.
Browser viewers expose setView(viewSpec), resetView(), savePNG(options),
and saveGIF(options). Export options include filename, download,
returnDataUrl, scale, width, height, transparent, backgroundColor,
and for GIF, frames, delay, and sampleInterval. Promises resolve with
{ ok, type, filename, dataUrl?, width?, height? } or reject with an Error
that carries code, message, type, and when available requestId.
OverlayViewer.saveGIF() rejects with code: "unsupported_export".
Python viewers expose headless save_png() and save_gif() when installed
with the export extra:
viewer = MolecularViewer(atoms, viewPreset="top-c")
viewer.save_png(
"top.png",
width=1600,
height=1200,
transparent=False,
background_color="#ffffff",
)
viewer.save_gif("trajectory.gif", frames=30, quality="high")
PNG quality is controlled through scale, width, and height. GIF
quality="low" | "medium" | "high" maps to the GIF encoder sample interval.
OverlayViewer.save_gif() is unsupported because overlay animation is not a
GIF export surface yet. The CLI still does not provide --save-png or
--save-gif.
Supported Formats
Input files are handled through ASE in Python and ase-ts in the VS Code extension. Common formats include xyz, extxyz, cif, pdb, vasp, POSCAR, and CONTCAR.
Viewer clipboard export supports:
| Export format | Notes |
|---|---|
xyz |
Simple coordinates for current frame or trajectory |
extxyz |
Includes cell metadata and fixed/move-mask constraint data when present |
cif |
Includes cell/periodic structure data; constraints are ignored because CIF has no standard FixAtoms field |
POSCAR |
Includes cell and selective-dynamics flags for fixed/move-mask constraints |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aseview-0.0.12.tar.gz.
File metadata
- Download URL: aseview-0.0.12.tar.gz
- Upload date:
- Size: 1.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f72f78afbdab8b60f74b60b94054d8d143272458d4bf8b734d27c3815925add1
|
|
| MD5 |
58f745c211e6c29331614a5f463a2ffd
|
|
| BLAKE2b-256 |
fb0fc597b968f10a244f7ffbe824e981a898c0151a856de1af76a63a945b84da
|
Provenance
The following attestation bundles were made for aseview-0.0.12.tar.gz:
Publisher:
publish.yml on kangmg/aseview
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aseview-0.0.12.tar.gz -
Subject digest:
f72f78afbdab8b60f74b60b94054d8d143272458d4bf8b734d27c3815925add1 - Sigstore transparency entry: 1918645633
- Sigstore integration time:
-
Permalink:
kangmg/aseview@b22741d5631ec188c1a8d050854d2c51c2759881 -
Branch / Tag:
refs/tags/v0.0.12 - Owner: https://github.com/kangmg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b22741d5631ec188c1a8d050854d2c51c2759881 -
Trigger Event:
push
-
Statement type:
File details
Details for the file aseview-0.0.12-py3-none-any.whl.
File metadata
- Download URL: aseview-0.0.12-py3-none-any.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96186126b382eeb79db14dfec346aece01ffb6add01b63a7413d35e783d00cb0
|
|
| MD5 |
10d61ccd9e9590b639eac25db1caa2a4
|
|
| BLAKE2b-256 |
b9493b2dbc15c70193c24dd34d8cf1ead27c2d79d565c07640435e527c23eaaf
|
Provenance
The following attestation bundles were made for aseview-0.0.12-py3-none-any.whl:
Publisher:
publish.yml on kangmg/aseview
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aseview-0.0.12-py3-none-any.whl -
Subject digest:
96186126b382eeb79db14dfec346aece01ffb6add01b63a7413d35e783d00cb0 - Sigstore transparency entry: 1918646087
- Sigstore integration time:
-
Permalink:
kangmg/aseview@b22741d5631ec188c1a8d050854d2c51c2759881 -
Branch / Tag:
refs/tags/v0.0.12 - Owner: https://github.com/kangmg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b22741d5631ec188c1a8d050854d2c51c2759881 -
Trigger Event:
push
-
Statement type: