# xyzrender draws publishable molecules without a GUI session

> xyzrender is a Python package and command line renderer that turns XYZ, PDB, CIF, SMILES and quantum chemistry output into vector SVG, PNG, PDF or GIF figures, deciding bond orders, aromatic rings, transition state dashes and stereochemistry labels from geometry alone. It suits computational chemists who want figures generated by a script instead of by hand.

**aligfellow/xyzrender** — Publication-quality molecular graphics.

- Repository: https://github.com/aligfellow/xyzrender
- Website: https://xyzrender.readthedocs.io
- Stars: 621 · Forks: 59
- Language: Python
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/aligfellow-xyzrender

## The workflow xyzrender removes from a structure figure

Most molecular visualisation software expects a person at a keyboard. You open a file in a viewer, rotate the molecule until it looks right, zoom until the bond widths read well on the page, export a raster at whatever resolution the dialog offered, and then draw the transition state bond by hand because the program cannot infer which bond is forming. xyzrender is built to remove those steps. The project describes itself as publication quality molecular graphics, and the core promise is that one command yields an oriented, depth cued structure with correct bond orders, aromatic ring rendering, automatic bond connectivity and automatic transition state and non covalent interaction detection.

The output side matters as much as the drawing side. SVG is the default and it is a vector, so the same file drops into a paper without a resolution argument. PNG, PDF and animated GIF come out of the same invocation, and the GIF is not a decorative extra: rotation, transition state vibration, trajectory, diffuse assembly and depth of field animations are listed as named animation types. For a working computational chemist that is the difference between a figure that can be regenerated later and one that has to be exported once and found again in a folder of similar files.

## Geometry is the source of bond orders, dashes and chirality

The detection work is where this project separates itself from a plain coordinate plotter, and it is delegated to two sibling packages rather than implemented from scratch. Bond orders and aromaticity, including double bonds, triple bonds and aromatic ring notation, are detected from geometry through xyzgraph. That same package supplies stereochemistry labels for R/S, E/Z, axial, planar cases such as metallocene and CIP, and helical chirality, plus detection of hydrogen bonds and other weak interactions that are drawn as dotted lines.

Transition state bonds are handled separately, by graphRC. A forming or breaking bond is drawn as a dashed line, and the decision is taken from imaginary frequency vibrations in the calculation output, not from the atom list. The implication for a user is practical: xyzrender can produce the transition state figure that normally takes manual drawing, but it can only do so if the imaginary frequency was actually located in the output you hand it. No imaginary mode, no dashed bond.

Connectivity is automatic as well, so no bond list needs to be supplied, and the SVG approach itself was built on and inspired by xyz2svg by Ksenia Briling. Orientation control, which is the part a manual viewer does well, is exposed through an interface to the related project v rather than being reinvented here.

## First render from a shell, starting with installation

The package publishes to PyPI and the project offers several installation routes, from a stable install to a one shot run without installing anything at all:

```bash
pip install xyzrender                                              # stable from PyPI
uv tool install xyzrender                                          # or via uv
uvx xyzrender mol.xyz                                              # try without installing
pip install git+https://github.com/aligfellow/xyzrender.git        # from source
```

The third line is the interesting one for a first look, because uvx fetches the tool, runs it on the file you name and leaves nothing behind in your environment. Optional extras are declared in the project metadata: smi pulls in rdkit, cif pulls in ase, shelxl pulls in shelxfile, v pulls in vmol, and all installs the union of those. Python 3.10 or newer is required.

Once installed, the basic invocations look like this:

```bash
xyzrender caffeine.xyz                            # XYZ → SVG, auto-oriented
xyzrender calc.out --ts                           # QM output with TS bonds
xyzrender caffeine.xyz --config pmol
```

The middle example is the interesting one, since --ts switches on the transition state detection and pairs it with a quantum chemistry output file rather than a plain coordinate file. The third example shows the preset mechanism: pmol is one of the built in style presets.

## Presets cover the common cases, JSON configs cover the rest

The built in presets are listed as default, flat, paton, pmol, skeletal, bubble, vdw, tube, mtube, btube, wire and graph, which is a spread from flat two dimensional schemes through ball and stick and space filling styles to wireframe and graph only output. Every setting underneath them is overridable, and the project is explicit that colors, radii, bond widths, gradients and fog are all exposed through command line flags or a custom JSON config file.

The flags cover a lot of ground. Bond display rules can selectively hide or add bonds by element category such as M, sbm, L or het, by element pair such as M-L or Fe-het, by pi coordination as M-pi, or by atom index, and a haptic mode replaces pi coordination fans with single centroid bonds. Styling reaches per atom fill opacity, radius scaling by element, category or index, style regions, atom property colormaps with a colorbar, and depth of field or depth fog. Annotations cover distances, angles, dihedrals, custom labels, atom indices and 3D vector arrows for dipoles, forces and fields.

Surfaces are the heaviest feature area: molecular orbitals, electron density, ESP colormapping, NCI surfaces and van der Waals spheres, in solid, mesh, contour and dot styles, with lobe outlines for opaque molecular orbitals and interlocked silhouette vdW spheres. The JSON config file matters for a publication workflow, because the same configuration can be stored beside the calculation and reused for every figure in a series rather than retyped as flags.

## Overlay, conformers and periodic structures extend past a single molecule

Three features push xyzrender beyond drawing one isolated structure. Structural overlay puts two structures on top of each other in contrasting colours, and the alignment is automatic: centres are placed on the metals when metals are present, otherwise it falls back to fuzzy substructure matching that tolerates atom substitutions, and finally to geometric best fit. The --align-atoms override exists for cases where the automatic choice is wrong, and --no-align keeps raw coordinates so you can place structures by hand.

The conformer ensemble mode overlays all frames from a multi frame XYZ trajectory, with palette colouring and opacity control, which is the usual way to show a reaction path or a sampling run. GIF animations cover rotation, transition state vibration, trajectory, diffuse or assembly behaviour, and depth of field.

Crystal and periodic structures are handled as a separate category with unit cell box, ghost atoms, supercells and crystallographic axis arrows. The lattice is auto detected from VASP POSCAR, Quantum ESPRESSO pw.in, SIESTA FDF, ABINIT, CP2K, SHELXL .res and .ins files, CIF, and extXYZ headers carrying a Lattice= entry. The convex hull tools go further again, drawing semi transparent facets over selected atoms or rings, the exposed faces of molecular cages, and pores, which is how cage and host structures are usually shown.

## A Python package first, with Jupyter and a web front end

xyzrender is packaged under src/ with the entry point declared as a console script named xyzrender, and the project declares support for running from Python or Jupyter as well as from the command line. The dependency list is short and readable: numpy, xyzgraph for the graph work described earlier, cclib for reading calculation outputs, graphrc for the transition state detection, cairosvg and resvg-py for rasterisation, Pillow for image handling, and ipykernel for the notebook side. Package data includes the preset JSON files, so the built in styles ship with the wheel.

The same code base is exposed through a Streamlit web application maintained by BNNLab at xyzrender-web.streamlit.app, which is a reasonable way to try options interactively before committing them to a config file.

For development, the repository ships a justfile rather than a Makefile, with a check target that runs lint, type and test in sequence. Linting and formatting are ruff commands, typing is checked with ty, and tests run under pytest with coverage:

Setup is uv sync --dev followed by a pre-commit install. The project also carries a CITATION.cff file and a Read the Docs configuration, which tells you something about the intended audience: the figures are expected to end up in a paper, and the software itself is expected to be cited.

## Where the approach stops working

The first limitation is that every structural decision is inferred. Bond orders, aromaticity, stereochemistry labels and dashed transition state bonds are read out of geometry and frequencies, so a structure with unusual bonding, a metal centre whose coordination the detector misreads, or a file with no imaginary frequency will produce a confident picture that is quietly wrong. The documentation does not describe an override for individual inferred bonds, and the bond display rules control which bonds are drawn rather than how their order is judged.

The second limitation is the absence of a GUI. Every orientation and camera choice in xyzrender comes from the automatic heuristics or from the interface to v. That is a good default for a script and a poor one for someone who wants to hand compose a scene, set up a lighting and composition for a cover figure, or compare several candidate views side by side.

A third practical point sits in the dependency graph. Several advertised input formats are not available in the base install. SMILES needs the smi extra with rdkit, CIF needs the cif extra with ase, and SHELXL needs the shelxfile extra, so a script that quietly assumes CIF support will fail on a fresh environment until those extras are installed. The MIT licence permits use in published work provided its copyright notice is retained., and the orientation and SVG foundations are attributed to the upstream projects they were inspired by.

## Conclusion

Adopt xyzrender when the figures have to be reproducible, since the same command that renders a structure during a workflow also produces the SVG you paste into a paper, and when the chemistry is already in files such as XYZ, QM output or CIF that the tool reads directly. Do not adopt it as a viewer for interactive exploration or for hand-tuned artistic scenes, since there is no GUI and the built in presets are the starting point rather than the destination. Before you commit, check that the format your calculation produced is in the supported list and that the automatic detection matches your chemistry, because bond orders, transition state dashes and stereochemistry labels are inferred rather than read from your input file, and confirm the installed version since the release tags on GitHub trail the version declared in pyproject.toml.

## FAQ

### How do I install xyzrender?

The project lists pip install xyzrender for the stable PyPI release, uv tool install xyzrender as an alternative, uvx xyzrender for a run without installing, and a direct install from the git repository. Python 3.10 or newer is required, and optional extras such as smi, cif, shelxl and v install the extra packages those formats need.

### Which file formats can xyzrender read?

The supported list covers XYZ, mol/SDF, MOL2, PDB, SMILES, CIF, SHELXL and cube files, along with quantum chemistry input and output from Gaussian, ORCA, NWChem, Q-Chem, Psi4, MOPAC, GAMESS, Turbomole, VASP, Quantum ESPRESSO, SIESTA, ABINIT and CP2K. Periodic structures are auto detected from POSCAR, pw.in, FDF, SHELXL res and ins files, CIF and extXYZ Lattice headers.

### Does xyzrender draw transition state bonds automatically?

Yes. Forming and breaking bonds are rendered as dashed lines, detected from imaginary frequency vibrations through the graphRC package. That means the detection works on a quantum chemistry output file, as in the documented invocation xyzrender calc.out --ts, and it depends on the calculation actually containing a located imaginary mode.

### Can xyzrender output SVG for a paper?

Vector SVG is the default output, and PNG, PDF and animated GIF are produced from the same command. Presets and overrides are available as command line flags or through a custom JSON config file, so a style used for one figure can be reused for a whole series.

### Is xyzrender still being updated?

The repository is not archived and the last push was on 2026-09-28. Tagged releases include v0.3.1 on 2026-05-31, v0.2.6 on 2026-04-15 and v0.2.0 on 2026-03-08, while pyproject.toml declares version 0.3.9, so the packaged version runs ahead of the published tags.

## Sources

- [aligfellow/xyzrender on GitHub](https://github.com/aligfellow/xyzrender)
- [License: MIT](https://github.com/aligfellow/xyzrender/blob/main/LICENSE)
- [Project website](https://xyzrender.readthedocs.io)
- [README](https://github.com/aligfellow/xyzrender/blob/main/README.md)
- [Releases](https://github.com/aligfellow/xyzrender/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/aligfellow-xyzrender
