eisfit
eisfit is a lightweight Python package for fitting electrochemical impedance spectroscopy (EIS) data and extracting equivalent-circuit parameters.
The package supports a two-arc equivalent circuit with either a CPE-type low-frequency tail or a semi-infinite Warburg tail:
Z = jωL + R0 + (R1 || CPE1) + (R2 || CPE2) + tail
It is designed for battery EIS analysis workflows where users need a simple Python API, a command-line tool, and reproducible fitted outputs.
Features
- Load EIS data from CSV, XLS, and XLSX files
- Fit complex impedance data with bounded multi-start least squares
- Use either a flexible CPE tail or a Warburg diffusion tail
- Export fitted parameters, simulated impedance, residuals, and Nyquist plots
- Run from Python notebooks, scripts, or the command line
- Use included demo files to test the workflow immediately after cloning
Installation
Install the released package from PyPI:
pip install eisfit
For local development from a cloned repository:
pip install -e ".[dev]"
Quick Start
Fit one EIS file directly:
from eisfit import fit_file
result = fit_file("my_eis.csv", tail="cpe", n_starts=40)
print(result.parameters)
print(result.rmse, result.nrmse)
Convergence and diagnostic records
Only optimizer starts that converge and return finite parameters, residuals,
cost, fitted impedance and fit error can be selected. The lowest-cost accepted
start is returned. If every start fails, fit() and fit_file() raise
FitConvergenceError instead of returning an unconverged parameter set:
from dataclasses import asdict
from eisfit import FitConvergenceError, fit
try:
result = fit(freq, Zexp)
except FitConvergenceError as error:
attempts = [asdict(attempt) for attempt in error.attempts]
else:
print(result.diagnostics)
Each attempted start records its index, optimizer success/status/message, evaluation count, cost, acceptance and rejection reason. A failed file fit does not write new fitted outputs. The CLI reports convergence failures as JSON and exits with status 1; a folder run continues with the remaining files and exits with status 1 if any file fails. Existing outputs from earlier runs are not removed, so consumers should use the current result's returned paths.
Convergence is a numerical termination condition. It does not establish a
unique solution, adequate fit quality or a physical interpretation.
identifiability_status is explicitly not_assessed.
Arc parameter ordering
Reported R1/Q1/n1 and R2/Q2/n2 are ordered by increasing characteristic
time tau = (R * Q) ** (1 / n) for each parallel R-CPE branch. Arc 1 therefore
has the higher characteristic frequency. Exact time ties use (R, Q, n) as
a deterministic secondary ordering. The full fitted spectrum is unchanged.
This convention prevents an arbitrary exchange of the two branch labels. It does not assign SEI/charge-transfer processes, establish identifiability, or track the same physical arc across spectra, especially when the times overlap or cross.
result.parameters, p_opt, staged fit errors, parameter_bounds and
bound_hits use the reported order. result.optimizer retains SciPy's
original solver order, including x and Jacobian columns. To relate them:
reported = result.optimizer.x[list(result.parameter_permutation)]
The permutation and effective parameter bounds are included in
result.diagnostics. Custom bounds are permuted with their branch, so bound
warnings remain associated with the correct reported parameter.
Load the data first when you want direct access to frequency and impedance arrays:
from eisfit import fit, load_eis
freq, Zexp = load_eis("my_eis.csv")
result = fit(freq, Zexp, tail="warburg")
print(result.parameters)
freq is the frequency array in Hz. Zexp is the measured complex impedance array:
Zexp = Zreal + 1j * Zimag
Input Data
Input files should contain at least three columns:
| Quantity | Meaning |
|---|---|
| frequency | Frequency in Hz |
| real impedance | Real part of impedance, usually Zreal or Zre |
| imaginary impedance | Imaginary part of impedance, usually Zimag or Zim |
Extra columns are allowed. eisfit tries to infer common column names automatically.
Example CSV:
Frequency_Hz,Zreal_Ohm,Zimag_Ohm
100000,0.0182,-0.0014
79432.8,0.0184,-0.0017
63100,0.0187,-0.0021
Models
Default CPE-tail model:
tail = 1 / (Qd * (jω)^nd)
parameters = [L, R0, R1, Q1, n1, R2, Q2, n2, Qd, nd]
Warburg-tail model:
tail = σ / sqrt(jω)
parameters = [L, R0, R1, Q1, n1, R2, Q2, n2, sigma]
The CPE tail keeps the diffusion-like exponent free. The Warburg tail uses the traditional semi-infinite Warburg form.
Command Line
Fit one file:
eisfit my_eis.csv --out-dir outputs --n-starts 40
Use the Warburg tail:
eisfit my_eis.csv --tail warburg --out-dir outputs --n-starts 40
Fit all matching files in a folder:
eisfit my_eis_folder --pattern "*.csv" --out-dir outputs --n-starts 20
Outputs
For each fitted file, eisfit can generate:
- fitted equivalent-circuit parameters
- simulated impedance values
- residuals between measured and fitted impedance
- Nyquist plot PNG
- Excel output table for downstream analysis
- optimizer-attempt audit sheet in the Excel output
*_fit_diagnostics.jsoncontaining parameters, solver diagnostics and the actual requested fitting configuration, with effective bounds in diagnostics
Demo
The repository includes example EIS files and a demo notebook:
examples/demo_fit_zenodo_dataset.ipynb
You can run the notebook after installing the local development environment:
pip install -e ".[dev]"
jupyter notebook
Development
Run the test suite:
pytest
Run a basic import/compile check:
python -m compileall src tests
Build the package locally:
python -m build
Release
PyPI releases are built from the clean public package branch using GitHub Actions and Trusted Publishing. See RELEASE.md for the release workflow.
License
The package code is released under the MIT License.
Metadata
Release files for eisfit 0.1.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 | Provenance | Actions |
|---|---|---|---|---|
| eisfit-0.1.1.tar.gz | 13.3 kB | With provenance | Details for eisfit-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| eisfit-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for eisfit-0.1.1-py3-none-any.whl |
Total release size: 29.7 kB
Release files / eisfit-0.1.1.tar.gz
| Download URL | eisfit-0.1.1.tar.gz |
|---|---|
| Size | 13.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5116e2de559212edc3146977c45838cac38c4417d37f413d7edaf395b108243
|
|
BLAKE2b-256 checksum How to use checksums |
374a99eecf577d5d079adc838ba9eb0be39564a230b0e99232dacc5a9466cb35
|
| 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 Oct 13, 2026.
Transparency logRelease files / eisfit-0.1.1-py3-none-any.whl
| Download URL | eisfit-0.1.1-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5c46d7b717aa038ef8d5878291eadc28a5860349ef73794a191259fd75518fb6
|
|
BLAKE2b-256 checksum How to use checksums |
3dacc2148c210ceff451c9aaf6c1b7dcd997f0127cd6f18c018d56eab9af7b63
|
| 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 Oct 13, 2026.
Transparency logSecurity for eisfit 0.1.1
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for eisfit-0.1.1.tar.gz
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 Oct 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.