One data format for every program, and one viewer for every figure.
Lab data comes from many programs, written in many programming languages: measurement scripts, notebooks, simulations, instrument software. Each plots with its own library, so figures from different programs, or from last year and this year, never look alike and are hard to compare. LBD fixes this:
- Every program saves its data as an
.lbdfile, using the small LBD module for its programming language. The same file reads back identically in every supported language. - LBD Viewer opens every
.lbdfile and draws it with one matplotlib style system. A figure looks the same whichever program made the data, and what you see is exactly what exports to PDF for your paper.
Documentation: patrick-csliu.github.io/lbd, with a quick start, examples with their figures, and every feature of the viewer.
LBD keeps what you measured and how figures look apart, and puts them together only when it draws:
- Data file (
.lbd): the axes you swept, the values you measured, units, labels and metadata. Optionally a saved view: what to plot by default. Written by your own programs, in any supported language. - Style: size, fonts, line widths, ticks, colours, colour maps, and fixed scales per
quantity. A named preset on your computer, or a
.lbd.jsonstyle file to share. - Figure: LBD Viewer and Python's
lbd.plotdraw the data file with the style, with the same code, on screen and in PDF, SVG or PNG at the real size.
Keep one style, and every figure matches: across datasets, programs and years. Change the style once, and every figure follows; the data is never touched. More in How LBD works.
- The
.lbdformat: plain HDF5 inside, so HDFView and h5py can also open it.- Axes with units and labels; N-D values; complex and boolean data; nested metadata.
- The same array shape in every language: no transposing.
- Version checks, so old tools never misread new files.
- Language modules: the same API in every supported language, today Python (
lbd), MATLAB (lbd.*) and Julia (LBD), verified by a cross-language test matrix. More languages can be added (Adding a language). lbd.plotfor Python: the viewer's styles and plot types in your own scripts:- plot data straight from memory, without saving it first;
- make your own matplotlib figures with the same size, fonts, colours and line widths;
- annotations (lines, text, arrows, shapes) as matplotlib calls, saved with the file's view.
- Styles shaped like matplotlib (Figure → Axes → frame, axis, ticks, legend, …):
- presets shared between the viewer and Python;
- style files (
*.lbd.json) to keep with a paper; .mplstyleexport for plain matplotlib users.
- LBD Viewer (Windows, macOS, Linux):
- a folder panel with search and a right-click menu (show in Explorer, copy path, rename, move to the Recycle Bin);
- curves, scatter plots (also value vs value, the complex I/Q plane, colour by a third quantity) and heat maps; complex data as magnitude/dB/phase; sliders (or typed values) for higher dimensions, and single-point axes shown as fixed parameters;
- several browser tabs that work together: numbered pages, move tabs between them with their unsaved settings, one page per file;
- style presets, with fixed colour scales per quantity for fair comparisons;
- save a view (plot settings, style, annotations) into the file;
- export PDF/SVG/PNG/JPG at an exact physical size, with a Save as dialog;
- images (PNG, JPEG, TIFF, SVG, …) shown with their metadata, view only;
- light, dark or system theme;
- double-click any
.lbdfile to open it in the viewer page you used last.
- Windows: run
LBD-Viewer-<version>-windows-x64-setup.exe. No admin rights are needed. - Linux: unpack the archive and run
./install.sh. - macOS: open the disk image and drag LBD Viewer to Applications; approve it once in System Settings → Privacy & Security (it isn't signed by a registered Apple developer).
After that, double-click any .lbd file. See Install.
The viewer's Language modules page shows the exact command for your computer:
| Language | Install |
|---|---|
| Python | pip install "<sdk>/python/lbd-<version>-py3-none-any.whl[plot]" ([plot] adds lbd.plot) |
| MATLAB | double-click <sdk>/matlab/LBD.mltbx |
| Julia | using Pkg; Pkg.develop(path="<sdk>/julia") |
Python
import numpy as np, lbd
f = np.linspace(4e9, 8e9, 401); p = np.arange(-40, 1, 4.0)
d = lbd.Dataset(title="Resonator power sweep")
d.add_axis("power", p, unit="dBm", label="Power")
d.add_axis("freq", f, unit="Hz", label="Frequency")
d.add_value("S21", np.exp(1j * np.outer(p, f) * 1e-10), axes=["power", "freq"])
d.meta["T_mK"] = 12
d.save("sweep.lbd") # lbd.load("sweep.lbd")["S21"].data -> (11, 401)MATLAB
f = linspace(4e9, 8e9, 401); p = -40:4:0;
d = lbd.Dataset("Resonator power sweep");
d.addAxis("power", p, Unit="dBm", Label="Power");
d.addAxis("freq", f, Unit="Hz", Label="Frequency");
d.addValue("S21", exp(1i * (p' * f) * 1e-10), ["power" "freq"]);
d.Meta.T_mK = 12;
d.save("sweep.lbd"); % lbd.load("sweep.lbd").Values.S21.Data -> 11 x 401Julia
using LBD
f = collect(range(4e9, 8e9, 401)); p = collect(-40.0:4:0)
d = LBD.Dataset("Resonator power sweep")
add_axis!(d, "power", p; unit="dBm", label="Power")
add_axis!(d, "freq", f; unit="Hz", label="Frequency")
add_value!(d, "S21", exp.(1im .* (p * f') .* 1e-10), ["power", "freq"])
d.meta["T_mK"] = 12
LBD.save("sweep.lbd", d) # size(LBD.load("sweep.lbd")["S21"].data) -> (11, 401)Double-click sweep.lbd, or add its folder to the viewer's folder panel. Choose how to plot
it, then export the figure or save the view into the file.
Or plot it in Python with the same styles, from memory or from the file:
import lbd.plot as lp
fig = lp.plot(d, "heatmap", "S21", complex="db", style="default") # d: the Dataset above
lp.save(fig, "sweep.pdf")
import matplotlib.pyplot as plt
with lp.use("default"): # your own figure, same look
fig, ax = plt.subplots()
ax.plot(f, np.abs(d["S21"].data[0]))
fig.savefig("my_figure.pdf")The full documentation is a searchable website built from docs/ with
MkDocs and Material for MkDocs. It is online at
patrick-csliu.github.io/lbd, for the latest release
(it is updated when a release is published). LBD Viewer ships a copy that works offline and
matches the installed version: use Help in the viewer's top bar. To build or preview it
from the repository:
uv sync --all-packages --group docs
uv run mkdocs serve # live preview at http://127.0.0.1:8000
uv run mkdocs build --strict # the site in site/ (open site/index.html)The Python API reference and the style settings tables are generated from the code's docstrings, so they always match the code. Good starting points (Markdown sources):
| Quick start | Write a file, look at it, make matching figures, in each supported language. |
| Concepts | What a file contains, dimension order, types, names, versions. |
| Install | Viewer and modules: install, upgrade, uninstall. |
| Examples | Short scripts with their figures, explained step by step, and a "find an example by task" table. |
| LBD Viewer | Every feature of the viewer. |
| Styles | How styles work, every setting, fixed scales, style files. |
| Languages | Python · lbd.plot · MATLAB · Julia |
| Developers | Architecture, tests, HTTP API, extending, building releases. |
| File format spec | The exact HDF5 layout. |
spec/ file format specification (the contract every language follows)
languages/ one folder per language, all with the same shape + a language.toml manifest
python/ Python module `lbd`
matlab/ MATLAB package `+lbd`
julia/ Julia package `LBD`
_template/ starting point for a new language (see languages/README.md)
viewer/ LBD Viewer
src/lbd_viewer/ backend (Python package `lbd-viewer`, command `lbd-view`)
web/ user interface (React + TypeScript)
tests/crosslang/ every language reads every language's files (discovered from the manifests)
examples/ example .lbd files and the script that makes them
python/ example scripts + explanations (scripts/make_gallery.py builds docs/examples/)
packaging/ installer build files (PyInstaller, Inno Setup, Linux install scripts)
scripts/ test runner, version check, release build scripts
docs/ documentation sources (MkDocs; mkdocs.yml at the root)
Adding a language means adding a folder under languages/; the tests, the version check, the
installer and the viewer pick it up from its language.toml. See
Adding a language.
Keep the virtual environment outside synced folders, and exclude viewer/web/node_modules from
sync:
export UV_PROJECT_ENVIRONMENT=~/.venvs/lbd-dev
uv sync --all-packages --group docs # the lbd module, the viewer, dev and docs tools
(cd viewer/web && npm ci && npm run build) # the viewer's user interface
uv run python scripts/test_all.py # every test suite, every language
uv run lbd-view --dev examples/data # http://127.0.0.1:8765/?token=devThe full test and release instructions are in the developer guide.
| Part | Requirement |
|---|---|
| Viewer | 64-bit Windows 10/11, macOS 14+ (Apple Silicon or Intel), or a Linux desktop |
| Python module | Python 3.9+ (numpy, h5py; [plot] adds matplotlib, pydantic, platformdirs) |
| MATLAB module | MATLAB R2021b+ |
| Julia module | Julia 1.9+ (HDF5.jl, JSON3.jl) |
MIT, see LICENSE. Each language folder carries a copy, since a module can be installed from its folder alone.