Changelog¶
Notable changes to vitabel, newest first.
0.2.0a1 - 2026-10-22¶
First pre-release of 0.2: the package has been restructured, the time series
core is much faster, and the interactive plot has been rebuilt. Install it with
pip install --pre vitabel.
Breaking changes¶
Interactive plot: redrawing no longer clears the axes, so your own changes to the figure persist. If you re-applied them in a matplotlib
draw_eventhandler, remove it; for content that should follow the data, useplot.add_overlay(...)andplot.on("labels_changed", ...)(see the guide Interactive plots) (#302).Vitals.rec_start()/rec_stop()return the first / last sample of the non-empty channels (previously the earliesttime_start), andNonefor recordings without data (#303).Vitals.compute_etco2_and_ventilationsraises aTypeErrorfor unknown keyword arguments instead of ignoring them (#303).IntervalLabel.contains_timeraises aTypeErrorfor time zone aware timestamps (#304).Removed
Vitals.dats(#297) and names that were importable only by accident, such asvitabel.vitals.DataSlice(usevitabel.typing.DataSlice) orvitabel.utils.pd. All functions and constants that were importable fromvitabel.utilsstill are (#298).
Changed results¶
Re-running an analysis on the same data can give different results than with 0.1.1:
VitalDB recordings use the time zone of the recording instead of the one of the computer; labels saved from earlier imports can be shifted by the difference (#297).
Chest compression periods from the accelerometer (
find_CC_periods_acc) change for recordings with gaps or irregular sampling, and with them the ROSC prediction andmake_cprdat_analysis(#303).ROSC predictions are reproducible (they were partly random) (#299).
Plots: the series of
Vitals.plotshare one time axis (#241); with aresolution, channels show the minimum and maximum per interval, so peaks stay visible (#302).
Added¶
Loaders and analyses are also available as functions on channels in the new modules
vitabel.io,vitabel.analysis,vitabel.plotting, andvitabel.registry(e.g.detect_etco2_and_ventilations,predict_rosc); theVitalsmethods work as before (#298).Interactive plot: undo / redo (
ctrl+z/ctrl+y), events (plot.on(...)),plot.set_window(start, stop), and overlays that update with the data (FillBetween,HLine,VSpanfromvitabel.plotting) (#302).load_datawarns if the data in a file has been modified outside ofvitabel(#297).Documentation: a guide to interactive plots, label plot types (#268), an architecture overview, and this changelog.
Performance¶
Time series operations on large recordings are 10 to 500 times faster (creating channels,
get_data,save_data/load_data);compute_ventilation_volumeson 8 minutes of animal lab data takes 1 s instead of 173 s (#301).The interactive plot opens about 18 times faster (ZOLL example: 0.2 s instead of 3.9 s) (#302).
Fixed¶
make_cprdat_analysisworks again (it failed since 0.1.0), and includes the chest compression analysis for LIFEPAK and LUCAS recordings (#299).Loading:
read_zollcsvfailed for recordings without CPR (#277);add_defibrillator_recordingand the VitalDB import modified the passedmetadata(#297, #298).Time data: a
pd.Serieswith a non-default index, a leadingNaT, and multi-dimensional arrays were handled wrongly (#288, #303, #304).rec_start/rec_stopfailed for recordings with empty channels and for relative recordings;IntervalLabel.contains_timefailed for pandas timestamps (#303).Analysis:
compute_ventilation_volumesfailed with anOutOfBoundsTimedelta(#286); CC period and ROSC detection failed for some relative recordings;derivandintegratewere wrong for irregular sampling; the legacy keywordbreaththreshalways raised;cycle_duration_analysispickedccorcc_depthat random (#303).Static plots: misaligned series (#241); relative recordings not starting at 0 were not shown;
IntervalLabel.plot(plot_type="hline")failed; channels in milliseconds were not downsampled; collections without channels could not be plotted (#302); scatter labels with all values 0 were not drawn (#303).Interactive plot: annotations lost sub-second precision (#279, #280); “Apply” in the settings reset the y limits; the marker of a pending interval was missing in other subplots (#255) (#302).
Development¶
Snapshot tests for loaders, analyses, and registry outputs; tests for loading files saved with older versions; headless tests of the interactive plot (#297, #302, #307).
A CI lint job, and a release workflow check of tag, version, and pre-release status (#302, #304).
Locked development dependencies updated with security fixes (#305).
Contributors: @behackl, @sorlob.
0.1.1 - 2026-03-24¶
v0.1.1 focuses on smoother data import, more reliable interactive
annotation, expanded respiratory and ventilation analysis, and a more polished
documentation experience.
Highlights¶
Added EDF import support.
Improved data loading robustness, including better handling of missing values and compatibility with old and new corpuls nomenclature.
Fixed interactive annotation so the current zoom level is preserved while adding annotations.
Expanded respiratory and ventilation tooling with:
improved respiratory phase detection
support for filtering by interval labels
new inspiratory/expiratory, tidal, and cumulative volume calculations
improved handling of reverse airflow and SI units
clearer plot styling and labeling for respiratory metrics
Refined the project presentation across the package metadata, README, and docs to better frame
vitabelas an open-source Python framework for working with high-resolution physiological time series in critical care and perioperative research.Improved the documentation experience with a versioned documentation title and a new fundamentals notebook covering
Channel,Label,IntervalLabel, andTimeDataCollection.Improved package usability and maintenance with a better
Channelstring representation, updated installation/docs/citation metadata, and more stable tests after dependency updates.
Merged pull requests¶
EDF integration (#270, @sorlob)
Preserve zoom during annotation (#273, @behackl)
Citation metadata and README fixes (#261, @behackl)
Stabilize tests after dependency bump (#272, @behackl)
Add string representation to
Channel(#267, @sorlob)Add Conda installation instructions to README (#240, @sorlob)
Adapt corpuls loading to old and new nomenclature (#254, @sorlob)
Improve
na_valueshandling during loading (#252, @sorlob)
0.1.0 - 2025-06-30¶
New contributors: @sorlob, @grahamk1chop, @JohannesUWittig.
Breaking changes¶
Added / changed¶
Add method for truncating Vitals, Channel, Label (#21, @behackl)
Feature: plot
IntervalLabelas filled background regions when they don’t hold y-data (#28, @behackl)Fix typo in demo notebook (#29, @sorlob)
Improve initialization of variable in demo notebook (#30, @sorlob)
Make override for unit of
ppg(viaSpO2 %, Waveform) more robust (#37, @behackl)Update stylesheet.py for Bedmaster at CHOP (#44, @grahamk1chop)
Add keyword argument for filtering labels by their type (#34, @sorlob)
Use
Rectanglefrommatplotlibto filter plotting keyword arguments ofIntervalLabel(#47, @sorlob)fix #71: Add absolute time to data frame generated by
_timeseries_list_info(#83, @sorlob)Reorder columns in
infotables (#90, @sorlob)Let overview plots range over full range of plotted data by default; add
limited_overviewkeyword argument (#52, @sorlob)Add typing and improve implementation, documentation of datatype argument (#102, @sorlob)
Various improvements to CSV / data frame loading code (#104, @behackl)
Feature: area under threshold calculations (#77, @sorlob)
Add library version to exported data and check for version mismatch when loading (#106, @behackl)
Fix and improve handling of time offset, allow directly setting offset attribute (#111, @behackl)
Basic support: allow None / pandas.NaT / numpy.nan in time_index (#113, @behackl)
Cleanup label string data refactor (continued) (#133, @behackl)
Introduce
text_dataforLabelandIntervalLabel(#131, @sorlob)Improve interface of
to_csvmethod (#143, @sorlob)Minor improvements to automatic analysis methods (#135, @sorlob)
Improve code for choosing automatic preset for plot settings (#146, @sorlob)
Refactor dropdown menu (#140, @sorlob)
Properly support
text_dataforIntervalLabel(#137, @sorlob)Add Label for etco2 (#165, @sorlob)
Refactor input to
area_under_thresholdin form of newsourceargument (#175, @sorlob)Add selection for annotation preset for labels (#177, @sorlob)
Include adjacent non-included data points when plotting to avoid plots breaking at the ends (#192, @behackl)
Add
first_entryandlast_entryas properties ofTimeSeriesBase(#198, @sorlob)Make sure local
vitabelenvironment is installed for Binder environments (#195, @sorlob)Add visual feedback on adding partial
IntervalLabelannotation (#207, @sorlob)Allow creating
IntervalLabelby list of tuples of interval endpoints (#202, @sorlob)Add
Vitals.detach_label_from_channelas dedicated way of using data container to manage label attachments (#178, @behackl)Add code used in case processing of German Resuscitation Registry (#84, @sorlob)
Allow filtering channels by passing keyword arguments in more methods (#209, @sorlob)
feature: Add rename method to
Labelfor updating label names (#212, @sorlob)Refactor
Vitals.add_vitaldb_recording(#215, @sorlob)Improve information displayed in
infotable (#214, @sorlob)Allow querying channels / labels by their index (#220, @behackl)
Unify input arguments and checks for automatic analysis / computation methods (#219, @behackl)
Improve loading routine for stryker devices to extract metadata (#221, @sorlob)
Improve sorting of columns in
infotable (#224, @sorlob)Preparation of demo notebooks (#144, @sorlob)
Add method for creating time-scaled time series (#227, @behackl)
Add method for importing ventilatory feedback from EOlife export (#103, @sorlob)
Fixed¶
Fix textual labels on (fixed) axis height (#25, @behackl)
Improve robustness of loading ZOLL-json format (#42, @behackl)
Use correct method for filtering labels in
Vitalsclass (#61, @sorlob)Check if artist was generated before trying to set corresponding label (#56, @sorlob)
Cast data time types to avoid
UFuncTypeError(#68, @sorlob)Make
Vitals.rec_startandVitals.rec_stopmore robust in case of no contained channels (#74, @sorlob)Handle timestamp addition type error (#80, @sorlob)
Fix wrong
get_labelscall (#86, @sorlob)Fix wrong
typecall (#87, @sorlob)Improve time type detection in
TimeSeriesBaseclass (#82, @sorlob)Check unique timestamps (#94, @sorlob)
Improve handling of
time_indexcontainingnp.NaTentries (#109, @sorlob)Fix behavior of warning about empty time range query in
get_time_mask(#122, @sorlob)Fix
IntervalLabel.from_dict(#170, @sorlob)Set plot legend only once for
axvspan(#166, @sorlob)Make interactive plot checkbox menu population more robust (#180, @behackl)
Fix repainting of overview indicators after changes to overview plot (#182, @behackl)
Improve documentation and behavior of methods removing channels or labels (#183, @behackl)
Fix: make sure shift marker is redrawn when interactive plot is repainted (#189, @behackl)
Allow
Vitals-import ofpd.DataFramewith relative time index (#193, @behackl)Checked for empty channels before raising time type inconsistency error (#200, @sorlob)
Improve robustness of (interactive) plotting when empty channels / labels are specified (#204, @sorlob)
Removed downsampling happening during vitaldb import (#226, @sorlob)
Recompute resolution based on current figure width when resizing canvas (#239, @behackl)
Documentation¶
Setup basic API reference documentation (#14, @behackl)
API doc improvements (#17, @behackl)
Update README.md (#40, @sorlob)
Improve docstrings of
save_data,load_data(#39, @sorlob)Format DOIs as hyperlinks (#59, @sorlob)
Updated docstring for
get_label(#66, @sorlob)Improve documentation by creating various static pages and adding content to existing ones (#97, @behackl)
Include demo notebooks as statically rendered subpages in documentation (#231, @behackl)
Add proper bibliography in documentation (#232, @behackl)
Extend bibliography, add reference to Zotero group (#237, @sorlob)
Miscellaneous cleanup in bibliography (#238, @sorlob)
0.0.1 - 2025-01-16¶
Initial release.