hofmann
A modern Python reimagining of Methfessel's XBS ball-and-stick viewer (1995), named after August Wilhelm von Hofmann who built the first ball-and-stick molecular models in 1865.
hofmann renders crystal and molecular structures as depth-sorted ball-and-stick images, producing publication-quality static output (SVG, PDF, PNG) and trajectory animations (GIF, MP4) via matplotlib.
Features
- Static publication-quality output (SVG, PDF, PNG) via matplotlib
- Trajectory animations (GIF, MP4) with per-frame colouring
- XBS
.bsand.mv(trajectory) file formats - Optional ASE
Atomsand pymatgenStructureinteroperability - Periodic boundary conditions with automatic image expansion
- Coordination polyhedra with configurable shading and slab clipping
- Unit cell wireframe rendering
- Interactive viewer with mouse rotation, zoom, and keyboard controls
- Orthographic, perspective, and oblique (axonometric) projection
Installation
pip install hofmann
For ASE interoperability:
pip install "hofmann[ase]"
For pymatgen interoperability:
pip install "hofmann[pymatgen]"
For animation export (GIF/MP4):
pip install "hofmann[animation]"
Requirements
- Python 3.11+
- numpy >= 1.24
- matplotlib >= 3.7
- scipy >= 1.10
- ase >= 3.22 (optional)
- pymatgen >= 2024.1.1 (optional)
- imageio >= 2.30 (optional, for GIF animation export)
- imageio-ffmpeg >= 0.5 (optional, for MP4 animation export)
Quick start
From an XBS file
from hofmann import StructureScene
scene = StructureScene.from_xbs("structure.bs")
scene.render_mpl("output.svg")
From ASE Atoms
from ase.build import bulk
from hofmann import StructureScene, BondSpec
atoms = bulk("Si", "diamond", a=5.43)
bonds = [BondSpec(species=("Si", "Si"), max_length=2.8)]
scene = StructureScene.from_ase(atoms, bonds)
scene.render_mpl("si.pdf")
From a pymatgen Structure
from pymatgen.core import Lattice, Structure
from hofmann import StructureScene, BondSpec
lattice = Lattice.cubic(5.43)
structure = Structure(
lattice, ["Si"] * 8,
[[0.0, 0.0, 0.0], [0.5, 0.5, 0.0],
[0.5, 0.0, 0.5], [0.0, 0.5, 0.5],
[0.25, 0.25, 0.25], [0.75, 0.75, 0.25],
[0.75, 0.25, 0.75], [0.25, 0.75, 0.75]],
)
bonds = [BondSpec(species=("Si", "Si"), max_length=2.8)]
scene = StructureScene.from_pymatgen(structure, bonds)
scene.render_mpl("si.pdf")
Controlling the view
scene.view.look_along([1, 1, 0]) # View along [110]
scene.view.zoom = 1.5 # Zoom in
scene.view.set_perspective(0.3) # Mild perspective
scene.render_mpl("rotated.svg")
Interactive viewer
view, style = scene.render_mpl_interactive()
# Reuse the adjusted view for static output:
scene.view = view
scene.render_mpl("final.svg", style=style)
Documentation
Full documentation is available at hofmann.readthedocs.io, covering:
- Getting started -- installation and first renders
- Scenes and structures -- scenes, frames, bonds, polyhedra
- Rendering -- views, render styles, unit cells, axes
- Colouring -- per-atom data colouring, custom functions, multiple layers
- Animations -- trajectory animations, per-frame colouring
- Interactive viewer -- mouse and keyboard controls
- XBS file format --
.bsand.mvformat reference - API reference -- full autodoc API
Citing hofmann
If you use hofmann in published work, please cite it:
B. J. Morgan, hofmann, https://github.com/bjmorgan/hofmann
A machine-readable citation is available in CITATION.cff.
Licence
MIT. See LICENSE for details.
Metadata
Release files for hofmann 0.21.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hofmann-0.21.1.tar.gz | 124.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hofmann-0.21.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 262.4 kB
Release files / hofmann-0.21.1.tar.gz
| Download URL | hofmann-0.21.1.tar.gz |
|---|---|
| Size | 124.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ffbd556d6bbd8259a7ab32d58cb253e37704d87aca1d9bbd3248897a198a864b
|
|
BLAKE2b-256 checksum How to use checksums |
963913b4680c74570d207a6f99f78c3454aafc4210da38fbee1affa77e6ac9f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / hofmann-0.21.1-py3-none-any.whl
| Download URL | hofmann-0.21.1-py3-none-any.whl |
|---|---|
| Size | 138.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d160d86da7cb53e49a5b5cda3996f079a08eff9ad07d223379b8f9a38552a5a4
|
|
BLAKE2b-256 checksum How to use checksums |
d1f4cf37de8d41bb533afe4585fbb812450ec23ca11751aebe21cbeee4192006
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency log