Skip to main content

Gallery

A collection of visualization examples. Each example shows a live 3D preview and the code needed to reproduce it in Jupyter, React, or the VSCode extension.

Small Molecule System

small-moleculepdbbasic

Visualize a solvated small molecule system with distance-based bond detection.

import megane
from megane import Pipeline, LoadStructure, AddBonds, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("caffeine_water.pdb"))
ab = pipe.add_node(AddBonds(source="distance"))
v = pipe.add_node(Viewport())
pipe.add_edge(s.out.particle, ab.inp.particle)
pipe.add_edge(s.out.particle, v.inp.particle)
pipe.add_edge(ab.out.bond, v.inp.bond)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Crystal with Coordination Polyhedra

crystalxyzpolyhedraperiodic

Render TiO₆ coordination polyhedra on a perovskite crystal structure with periodic cell axes.

import megane
from megane import Pipeline, LoadStructure, AddBonds, AddPolyhedra, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("perovskite_srtio3_3x3x3.xyz"))
ab = pipe.add_node(AddBonds(source="distance"))
# TiO6 octahedra: center = Ti (22), ligand = O (8)
poly = pipe.add_node(AddPolyhedra(
center_elements=[22],
ligand_elements=[8],
max_distance=2.5,
opacity=0.5,
show_edges=True,
))
v = pipe.add_node(Viewport(cell_axes_visible=True))
pipe.add_edge(s.out.particle, ab.inp.particle)
pipe.add_edge(s.out.particle, poly.inp.particle)
pipe.add_edge(s.out.particle, v.inp.particle)
pipe.add_edge(s.out.cell, v.inp.cell)
pipe.add_edge(ab.out.bond, v.inp.bond)
pipe.add_edge(poly.out.mesh, v.inp.mesh)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Atom Filter

filtersmall-moleculeselection

Select solute atoms with a query and enlarge them 3× while fading solvent to 15% opacity, making the selection immediately obvious.

import megane
from megane import Pipeline, LoadStructure, Filter, Modify, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("caffeine_water.pdb"))
# Branch A: enlarge the solute (caffeine = first 24 atoms)
fc = pipe.add_node(Filter(query="index < 24"))
mc = pipe.add_node(Modify(scale=3.0, opacity=1.0))
# Branch B: fade the solvent (water = remaining atoms)
fw = pipe.add_node(Filter(query="index >= 24"))
mw = pipe.add_node(Modify(scale=1.0, opacity=0.15))
v = pipe.add_node(Viewport())
pipe.add_edge(s.out.particle, fc.inp.particle)
pipe.add_edge(fc.out.particle, mc.inp.particle)
pipe.add_edge(mc.out.particle, v.inp.particle)
pipe.add_edge(s.out.particle, fw.inp.particle)
pipe.add_edge(fw.out.particle, mw.inp.particle)
pipe.add_edge(mw.out.particle, v.inp.particle)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Dual Representation

filtermodifysmall-moleculeselection

Fan out the pipeline to render the solute in full detail while the solvent is dimmed and semi-transparent.

import megane
from megane import Pipeline, LoadStructure, AddBonds, Filter, Modify, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("caffeine_water.pdb"))
ab = pipe.add_node(AddBonds(source="distance"))
# Branch 1: caffeine (index < 24) — full size
f_solute = pipe.add_node(Filter(query="index < 24"))
m_solute = pipe.add_node(Modify(scale=1.3, opacity=1.0))
# Branch 2: water (index >= 24) — small and transparent
f_solvent = pipe.add_node(Filter(query="index >= 24"))
m_solvent = pipe.add_node(Modify(scale=0.8, opacity=0.15))
v = pipe.add_node(Viewport())
# Bonds
pipe.add_edge(s.out.particle, ab.inp.particle)
pipe.add_edge(ab.out.bond, v.inp.bond)
# Solute branch
pipe.add_edge(s.out.particle, f_solute.inp.particle)
pipe.add_edge(f_solute.out.particle, m_solute.inp.particle)
pipe.add_edge(m_solute.out.particle, v.inp.particle)
# Solvent branch
pipe.add_edge(s.out.particle, f_solvent.inp.particle)
pipe.add_edge(f_solvent.out.particle, m_solvent.inp.particle)
pipe.add_edge(m_solvent.out.particle, v.inp.particle)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Atom Labels

labelsfiltersmall-molecule

Generate per-atom text labels (element symbols) on a filtered subset of atoms.

import megane
from megane import Pipeline, LoadStructure, Filter, AddLabels, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("caffeine_water.pdb"))
# Focus on the solute molecule only
f = pipe.add_node(Filter(query="index < 24"))
lbl = pipe.add_node(AddLabels(source="element"))
v = pipe.add_node(Viewport())
pipe.add_edge(s.out.particle, f.inp.particle)
pipe.add_edge(f.out.particle, v.inp.particle)
pipe.add_edge(f.out.particle, lbl.inp.particle)
pipe.add_edge(lbl.out.label, v.inp.label)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Bond Filter

filterbondsmall-moleculeselection

Use a bond query to hide solvent bonds: select bonds touching a water atom and set their opacity to 0, leaving only intramolecular solute bonds visible.

import megane
from megane import Pipeline, LoadStructure, AddBonds, Filter, Modify, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("caffeine_water.pdb"))
ab = pipe.add_node(AddBonds(source="distance"))
# Select bonds that touch a water atom (atom_index >= 24) — these will be hidden
fb = pipe.add_node(Filter(bond_query="atom_index >= 24"))
# Set opacity=0 on the selected (water) bonds to hide them
mb = pipe.add_node(Modify(opacity=0.0))
v = pipe.add_node(Viewport())
pipe.add_edge(s.out.particle, ab.inp.particle)
pipe.add_edge(ab.out.bond, fb.inp.particle) # bond → filter "in" port
pipe.add_edge(fb.out.particle, mb.inp.particle) # filter "out" → modify "in"
pipe.add_edge(mb.out.particle, v.inp.bond) # modify "out" → viewport bond
pipe.add_edge(s.out.particle, v.inp.particle)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Trajectory Animation

trajectoryanimationsmall-moleculextc

Load an XTC trajectory file alongside the structure to animate molecular vibrations frame by frame. The gallery preview auto-plays a built-in vibration demo.

import megane
from megane import Pipeline, LoadStructure, LoadTrajectory, AddBonds, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("caffeine_water.pdb"))
traj = pipe.add_node(LoadTrajectory(xtc="caffeine_water_vibration.xtc"))
ab = pipe.add_node(AddBonds(source="structure"))
v = pipe.add_node(Viewport())
pipe.add_edge(s.out.particle, ab.inp.particle)
pipe.add_edge(s.out.particle, traj.inp.particle) # topology for XTC
pipe.add_edge(s.out.particle, v.inp.particle)
pipe.add_edge(ab.out.bond, v.inp.bond)
pipe.add_edge(traj.out.traj, v.inp.traj)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Vector Arrows

vectorforcessmall-molecule

Overlay per-atom vector data (forces or velocities) as arrows using load_vector and vector_overlay nodes. The gallery preview shows synthetic radial arrows.

import megane
from megane import Pipeline, LoadStructure, AddBonds, LoadVector, VectorOverlay, Viewport
pipe = Pipeline()
s = pipe.add_node(LoadStructure("caffeine_water.pdb"))
ab = pipe.add_node(AddBonds(source="distance"))
vec = pipe.add_node(LoadVector("demo_vectors.vec"))
# Scale arrows to a visible length
overlay = pipe.add_node(VectorOverlay(scale=1.5))
v = pipe.add_node(Viewport())
pipe.add_edge(s.out.particle, ab.inp.particle)
pipe.add_edge(s.out.particle, v.inp.particle)
pipe.add_edge(ab.out.bond, v.inp.bond)
pipe.add_edge(vec.out.vector, overlay.inp.vector)
pipe.add_edge(overlay.out.vector, v.inp.vector)
viewer = megane.MolecularViewer()
viewer.set_pipeline(pipe)
viewer

Adding Your Own Example

To contribute a new gallery example, edit docs/src/gallery/registry.ts and add an entry to the galleryExamples array.

FieldDescription
idUnique kebab-case identifier (used as HTML anchor)
titleShort display name
descriptionOne-sentence description
tagsArray of lowercase tag strings
snapshotUrlPath to a snapshot JSON in docs/public/data/
code.jupyterPython snippet for Jupyter
code.reactTSX snippet using PipelineViewer
code.vscodemegane.json content (SerializedPipeline JSON)