Library / SDK
pymeasure/pymeasure avatar
pymeasure/pymeasure

PyMeasure: instrument drivers and an experiment runner that live in the same package

Scientific measurement library for instruments, experiments, and live-plotting

791 stars473 forksPythonMIT

At a glance

What is it?
PyMeasure holds a repository of instrument classes and a system for running experiment procedures with graphical live plotting and experiment queues, and the two halves are independent. The dependency list is the quickest way to see what it is for: numpy, pandas, pint, pyvisa and pyserial, with pyqtgraph, pyzmq and pyvisa-sim as extras.
Who is it for?
PyMeasure fits a lab that drives instruments over serial or VISA, wants measurements recorded with units and plotted live, and would rather not write the driver layer or the queueing layer itself. It does not fit a team that needs instrument control inside a continuous integration pipeline without hardware attached, and it does not fit a lab whose instruments speak a protocol this library does not cover.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two halves that happen to ship together

PyMeasure is described as a scientific measurement library for instruments, experiments and live-plotting, and the README splits it cleanly in two.

The first part is a repository of instrument classes, which is the driver layer, one class per instrument family speaking the protocol that instrument uses. The second is a system for running experiment procedures, which provides graphical interfaces for graphing live data and managing queues of experiments.

The sentence that makes the design explicit is that both parts of the package are independent, and when combined provide all the necessary requirements for advanced measurements with only limited coding.

That independence is the useful property. A lab that only wants to talk to a source meter and log a voltage does not have to adopt the experiment runner, and a lab that has its own instrument layer can use the procedure system and plotting without replacing its drivers. The package is a repository of both, not a framework that insists on both.

The audience is stated in the packaging rather than the prose: the classifiers list Intended Audience Science/Research and Topic Scientific/Engineering, and the project is on PyPI, on conda-forge, on Read the Docs and archived with a Zenodo DOI for citation, which is the standard set of distribution channels for a research tool rather than an application library.

The dependency list is the real specification

The runtime dependencies in pyproject.toml are short and each one tells you what kind of measurement work the library expects:

toml
dependencies = [
    "numpy>=1.6.1,<3",
    "pandas>=2.1,<4",
    "pint",
    "pyvisa>=1.9",
    "pyserial>=2.7",
]

numpy and pandas for the data side, pint for units, and then the two that matter most for an instrument lab: pyvisa, which is the standard way to talk to instruments over the VISA protocol used by a large amount of test and measurement hardware, and pyserial for the instruments that speak a serial line and nothing else.

pint deserves a second look, because it is the reason the library can hold a measurement with its unit attached rather than as a bare float. In a lab where a value could be volts, millivolts or amperes, having the unit inside the number is not a convenience, it is what stops a plot axis from being wrong. The dependency is there in the base install, which says the library treats units as part of the data rather than as an optional extra.

The upper bounds are worth noticing too. numpy is capped below 3 and pandas below 4, so the project is tracking the current major releases of both and will refuse a future major until it has tested against it.

The picture that emerges is a library for people who have real hardware on a bench and a Python script that needs to command it.

The extras decide what the experiment side can do

Everything beyond the base install is an extra, and they are organised by what you want to do rather than by dependency kind.

toml
[project.optional-dependencies]
gui = [
    "pyqtgraph>=0.12",
    "qtpy>=2.4",
]
tcp = [
    "pyzmq>=16.0.2",
    "cloudpickle>=0.3.1",
]

The gui extra pulls in pyqtgraph for the live plotting and qtpy as the Qt binding layer, and there is a comment in the file reminding you to install pyqt or pyside manually as desired, so the binding is your choice rather than the project's.

The tcp extra is the one that changes the architecture rather than the interface. pyzmq and cloudpickle are there so that experiment procedures can be distributed over a network, which is the difference between one script driving one bench and a lab where a controller process schedules work across several workers. cloudpickle is what makes that possible, because it can serialise the procedure objects themselves rather than requiring them to be importable by name on the far side.

The remaining extras are for development rather than use. The tests extra has pytest and pytest-cov, pytest-qt, and pyvisa-sim, which is a simulated VISA device, so the test suite can exercise instrument code without hardware present. The docs extra has Sphinx with the read the docs theme and the autodoc type hints extension, and the dev extra has pyright and ruff.

That last combination, pyright for types and ruff for linting and formatting, is the modern Python house style, and the presence of a .flake8 file at the root as well suggests the older tooling is still there for the files that have not been converted.

Getting started means the quick start guide and the examples directory

The quick start section of the README is short, and it is short because the work is in the documentation. The first step is to check out the documentation for the quick start guide, which covers the installation of Python and PyMeasure itself, and the second is to note that there are a number of examples in the examples directory that can help you get up and running.

The examples directory in the repository is worth a look, because the names describe the three shapes of work the library supports. There is a Basic directory, a Current-Voltage Measurements directory, and a Notebook Experiments directory, alongside a README in the examples folder itself.

Those three correspond to the three audiences. Basic is a minimal instrument interaction, Current-Voltage Measurements is a measurement with a physical quantity attached, which is where pint earns its place, and Notebook Experiments is the case where the plotting and the procedure system are used inside a notebook rather than a script.

The documentation itself is built with Sphinx and hosted on Read the Docs, with the badge in the README pointing at the latest version. The project is also archived on Zenodo with a DOI, which is how research software gets a citable version even when it is on PyPI and moves often.

For a reader deciding whether to adopt the library, the ordering that follows from all this is: read the quick start, browse the instrument classes in the pymeasure/ package for the hardware you own, then look at the examples that resemble the experiment you want to run.

Releases land about once a year, and the repo is set up for it

The tagged releases are v0.14.0 on 2024-05-22, v0.15.0 on 2025-01-15 and v0.16.0 on 2026-05-20, so the version moves roughly once a year with a zero major and a minor bump each time. The package is still classified as Development Status 4, Beta.

That cadence is normal for research software with a slow dependency and hardware in the loop, and the project is explicit that it is currently under active development, asking that issues be reported on its issues page.

The repository supports that process with a set of files that are worth naming, because they tell you what the maintainers consider part of the job. There is CHANGES.rst for the release notes, a RELEASE.md for the release process, CITATION.cff for the citation metadata that pairs with the Zenodo DOI, AUTHORS.txt, and a CODE_OF_CONDUCT-equivalent is not in the listing but the .github/ directory holds the workflows.

The continuous integration badge points at a workflow named pymeasure_CI.yml, and the README states that PyMeasure is tested with continuous integration on Linux, macOS and Windows for all supported Python versions. The supported versions are listed in the classifiers, from Python 3.10 through 3.14, and the pyproject requires 3.10 or newer.

There is also an AGENTS.md at the root, which in a project of this kind usually means the instructions for coding assistants working in the tree, and a .readthedocs.yml for the documentation build.

Where PyMeasure is the wrong tool

The first wrong fit is hardware PyMeasure does not have a class for. The library is a repository of instrument classes, and if your bench has a device that speaks a protocol nobody implemented, the library cannot help you. The related projects section is a clue to how that gap is handled: LECO Protocol is an open standard for laboratory equipment communication using modern protocols, pyleco is a Python library implementing LECO for distributed instrument control systems, and the Python Lab Automation Landscape is a curated collection of Python tools for laboratory automation and instrumentation. In other words, where a driver is missing, the answer is another package or another protocol, not a configuration.

The second is a batch job that has to run without a human and without a screen. The experiment system is described in terms of graphical interfaces for graphing live data and managing queues of experiments, and the plotting extra is a Qt stack. A headless pipeline that only needs to log readings would use the instrument classes and skip the rest, but anyone expecting the queueing and the live graph to work in a server without a display is on their own.

The third is a project that needs more than instruments and procedures. There is no analysis pipeline, no statistics and no data management here, and pandas is a dependency rather than a workflow, so the data ends up in your hands rather than in the library's.

The fourth is a team that has already written its own instrument layer and is happy with it. The independent design means PyMeasure is not forced on you, and the cost of switching is the driver rewrite plus the learning curve, which for a working lab is rarely worth it.

The fifth is a version-stability question. Beta classification, annual releases and a dependency floor on numpy and pandas mean the API is expected to move, so an experiment script written against v0.16.0 should be pinned rather than floated.

The licence is MIT, with the LICENSE.txt file at the root of the repository, so none of these constraints is about legal friction. They are all about what the library is, which is a bench-side toolkit for people who own instruments.

Editorial conclusion

PyMeasure fits a lab that drives instruments over serial or VISA, wants measurements recorded with units and plotted live, and would rather not write the driver layer or the queueing layer itself. It does not fit a team that needs instrument control inside a continuous integration pipeline without hardware attached, and it does not fit a lab whose instruments speak a protocol this library does not cover. Before adopting it, look at the instrument classes in pymeasure/ and the examples directory, because the coverage of your own hardware is the deciding factor.

Frequently asked questions

What is PyMeasure?

It is a scientific measurement library for instruments, experiments and live-plotting. The package contains a repository of instrument classes and a system for running experiment procedures with graphical interfaces for graphing live data and managing queues of experiments.

What does PyMeasure need to talk to instruments?

The base install pulls in pyvisa and pyserial, along with numpy, pandas and pint for the data and the units. The gui extra adds pyqtgraph and qtpy for live plotting, and the tcp extra adds pyzmq and cloudpickle so procedures can be distributed.

How do I install and start using PyMeasure?

The readme points to the quick start guide in the documentation for the installation of Python and PyMeasure, and to the examples directory, which contains Basic, Current-Voltage Measurements and Notebook Experiments examples that show the three common shapes of work.

Can PyMeasure be tested without instruments?

The tests extra includes pyvisa-sim, a simulated VISA device, along with pytest, pytest-cov and pytest-qt, so the test suite can exercise instrument code without hardware attached. The project is tested with continuous integration on Linux, macOS and Windows.

What licence is PyMeasure released under?

It is MIT licensed, with the LICENSE.txt file at the root of the repository, and the current release is v0.16.0 from 2026-05-20, with the project classified as Development Status 4, Beta.

Official sources

  1. License: MIT
  2. Project website
  3. pymeasure/pymeasure on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pymeasure-pymeasure.svg)](https://hysenlabs.com/projects/pymeasure-pymeasure)

Was this useful?