Package: neurokit2
The Python Toolbox for Neurophysiological Signal ProcessingNeuroKit2is a user-friendly package providing easy access to advanced biosignal processing routines.
Researchers and clinicians without extensive knowledge of programming or biomedical signal processing
cananalyze physiological data with only two lines of code.Quick Exampleimportneurokit2asnk# Download example datadata=nk.data("bio_eventrelated_100hz")# Preprocess the data (filter, find peaks, etc.)processed_data,info=nk.bio_process(ecg=data["ECG"],rsp=data["RSP"],eda=data["EDA"],sampling_rate=100)# Compute relevant featuresresults=nk.bio_analyze(processed_data,sampling_rate=100)Andboom💥 your analysis is done 😎DownloadYou can download NeuroKit2 fromPyPIpip install neurokit2orconda-forgeconda install -c conda-forge neurokit2If you’re not sure what to do, read ourinstallation guide.ContributingNeuroKit2 is the mostwelcomingproject with a large community of contributors with all levels of programming expertise.But the package is still far from being perfect!Thus, if you have some ideas forimprovement,new features, or just want tolearn Pythonand do something useful at the same time, do not hesitate and check out the following guide:Contributing to NeuroKitAlso, if you have developed new signal processing methods or algorithms and you want toincrease their usage, popularity, and citations, get in touch with us to eventually add them to NeuroKit. A great opportunity for the users as well as the original developers!You have spotted amistake? Anerrorin a formula or code? OR there is just a step that seems strange and you don’t understand?Please let us know!We are human beings, and we’ll appreciate any inquiry.DocumentationClick on the links above and check out our tutorials:GeneralGet familiar with Python in 10 minutesRecording good quality signalsInstall Python and NeuroKitIncluded datasetsAdditional ResourcesExamplesSimulate Artificial Physiological SignalsCustomize your Processing PipelineEvent-related AnalysisInterval-related AnalysisAnalyze Electrodermal Activity (EDA)Analyze Respiratory Rate Variability (RRV)Extract and Visualize Individual HeartbeatsLocate P, Q, S, and T waves in ECGAnalyze Electrooculography EOG dataDon’t know which tutorial is suited for your case?Follow this flowchart:CitationTheNeuroKit2paper can be foundhere🎉 Additionally, you can get the reference directly from Python by running:nk.cite()You can cite NeuroKit2 as follows:

- Makowski, D., Pham, T., Lau, Z. J., Brammer, J. C., Lespinasse, F., Pham, H.,
Schölzel, C.,&Chen, S. A. (2021). NeuroKit2: A Python toolbox for neurophysiological signal processing.
Behavior Research Methods, 53(4), 1689–1696. https://doi.org/10.3758/s13428-020-01516-y

Full bibtex reference:

@article{Makowski2021neurokit,
    author ={Dominique Makowski and Tam Pham and Zen J. Lau and Jan C. Brammer and Fran{\c{c}}ois Lespinasse and Hung Pham and Christopher Schölzel and S. H. Annabel Chen},
    title ={{NeuroKit}2: A Python toolbox for neurophysiological signal processing},
    journal ={Behavior Research Methods},
    volume ={53},
    number ={4},
    pages ={1689--1696},
    publisher ={Springer Science and Business Media{LLC}},
    doi ={10.3758/s13428-020-01516-y},
    url ={https://doi.org/10.3758%2Fs13428-020-01516-y},year = 2021,
    month ={feb}}Let us know if you used NeuroKit2 in a publication!Open a newdiscussion(select theNK in publicationscategory) and link the paper. The community would be happy to know about how you used it and learn about your research. We could also feature it once we have a section on the website for papers that used the software.Physiological Data PreprocessingSimulate physiological signalsYou can easily simulate artificial ECG (also12-Lead multichannel ECGs), PPG, RSP, EDA, and EMG signals to test your scripts and algorithms.importnumpyasnpimportpandasaspdimportneurokit2asnk# Generate synthetic signalsecg=nk.ecg_simulate(duration=10,heart_rate=70)ppg=nk.ppg_simulate(duration=10,heart_rate=70)rsp=nk.rsp_simulate(duration=10,respiratory_rate=15)eda=nk.eda_simulate(duration=10,scr_number=3)emg=nk.emg_simulate(duration=10,burst_number=2)# Visualise biosignalsdata=pd.DataFrame({"ECG":ecg,"PPG":ppg,"RSP":rsp,"EDA":eda,"EMG":emg})nk.signal_plot(data,subplots=True)Electrodermal Activity (EDA/GSR)# Generate 10 seconds of EDA signal (recorded at 250 samples / second) with 2 SCR peakseda=nk.eda_simulate(duration=10,sampling_rate=250,scr_number=2,drift=0.01)# Process itsignals,info=nk.eda_process(eda,sampling_rate=250)# Visualise the processingnk.eda_plot(signals,info)Cardiac activity (ECG)# Generate 15 seconds of ECG signal (recorded at 250 samples/second)ecg=nk.ecg_simulate(duration=15,sampling_rate=250,heart_rate=70)# Process itsignals,info=nk.ecg_process(ecg,sampling_rate=250)# Visualise the processingnk.ecg_plot(signals,info)Respiration (RSP)# Generate one minute of respiratory (RSP) signal (recorded at 250 samples / second)rsp=nk.rsp_simulate(duration=60,sampling_rate=250,respiratory_rate=15)# Process itsignals,info=nk.rsp_process(rsp,sampling_rate=250)# Visualise the processingnk.rsp_plot(signals,info)Photoplethysmography (PPG/BVP)# Generate 15 seconds of PPG signal (recorded at 250 samples/second)ppg=nk.ppg_simulate(duration=15,sampling_rate=250,heart_rate=70)# Process itsignals,info=nk.ppg_process(ppg,sampling_rate=250)# Visualize the processingnk.ppg_plot(signals,info)Electromyography (EMG)# Generate 10 seconds of EMG signal (recorded at 250 samples/second)emg=nk.emg_simulate(duration=10,sampling_rate=250,burst_number=3)# Process itsignals,info=nk.emg_process(emg,sampling_rate=250)# Visualise the processingnk.emg_plot(signals,info)Electrooculography (EOG)# Import EOG dataeog_signal=nk.data("eog_100hz")# Process itsignals,info=nk.eog_process(eog_signal,sampling_rate=100)# Plotnk.eog_plot(signals,info)Electrogastrography (EGG)Considerhelping us develop it!Physiological Data AnalysisThe analysis of physiological data usually comes in two types,event-relatedorinterval-related.Event-relatedThis type of analysis refers to physiological changes immediately occurring in response to an event.
For instance, physiological changes following the presentation of a stimulus (e.g., an emotional stimulus) are indicated by
the dotted lines in the figure above. In this situation, the analysis is epoch-based.
An epoch is a short chunk of the physiological signal (usually < 10 seconds), that is locked to a specific stimulus and hence
the physiological signals of interest are time-segmented accordingly. This is represented by the orange boxes in the figure above.
In this case, usingbio_analyze()will compute features like rate changes, peak characteristics, and phase characteristics.Event-related exampleInterval-relatedThis type of analysis refers to the physiological characteristics and features that occur over
longer periods of time (from a few seconds to days of activity). Typical use cases are either
periods of resting state, in which the activity is recorded for several minutes while the participant
is at rest, or during different conditions in which there is no specific time-locked event
(e.g., watching movies, listening to music, engaging in physical activity, etc.). For instance,
this type of analysis is used when people want to compare the physiological activity under different
intensities of physical exercise, different types of movies, or different intensities of
stress. To compare event-related and interval-related analysis, we can refer to the example figure above.
For example, a participant might be watching a 20s-long short film where particular stimuli of
interest in the movie appear at certain time points (marked by the dotted lines). While
event-related analysis pertains to the segments of signals within the orange boxes (to understand the physiological
changes pertaining to the appearance of stimuli), interval-related analysis can be
applied on the entire 20s duration to investigate how physiology fluctuates in general.
In this case, usingbio_analyze()will compute features such as rate characteristics (in particular,
variability metrics) and peak characteristics.Interval-related exampleHeart Rate Variability (HRV)Check-out ourHeart Rate Variability in Psychology: A Review of HRV Indices and an Analysis Tutorialpaperfor:a comprehensive review of the most up-to-date HRV indicesa discussion of their significance in psychological research and practicesa step-by-step guide for HRV analysis usingNeuroKit2You can cite the paper as follows:

- Pham, T., Lau, Z. J., Chen, S. H. A.,&Makowski, D. (2021).
Heart Rate Variability in Psychology: A Review of HRV Indices and an Analysis Tutorial.
Sensors, 21(12), 3998. https://doi:10.3390/s21123998Compute HRV indices using PythonTime domain: RMSSD, MeanNN, SDNN, SDSD, CVNN, etc.Frequency domain: Spectral power density in various frequency bands (Ultra low/ULF, Very low/VLF, Low/LF, High/HF, Very high/VHF), Ratio of LF to HF power, Normalized LF (LFn) and HF (HFn), Log transformed HF (LnHF).Nonlinear domain: Spread of RR intervals (SD1, SD2, ratio between SD2 to SD1), Cardiac Sympathetic Index (CSI), Cardial Vagal Index (CVI), Modified CSI, Sample Entropy (SampEn).# Download datadata=nk.data("bio_resting_8min_100hz")# Find peakspeaks,info=nk.ecg_peaks(data["ECG"],sampling_rate=100)# Compute HRV indicesnk.hrv(peaks,sampling_rate=100,show=True)>>>HRV_RMSSDHRV_MeanNNHRV_SDNN...HRV_CVIHRV_CSI_ModifiedHRV_SampEn>>>069.697983696.39534962.135891...4.829101592.0953721.259931MiscellaneousECG DelineationDelineate the QRS complex of an electrocardiac signal (ECG) including P-peaks, T-peaks, as well as their onsets and offsets.# Download dataecg_signal=nk.data(dataset="ecg_3000hz")# Extract R-peaks locations_,rpeaks=nk.ecg_peaks(ecg_signal,sampling_rate=3000)# Delineatesignal,waves=nk.ecg_delineate(ecg_signal,rpeaks,sampling_rate=3000,method="dwt",show=True,show_type='all')Signal ProcessingSignal processing functionalitiesFiltering: Using different methods.Detrending: Remove the baseline drift or trend.Distorting: Add noise and artifacts.# Generate original signaloriginal=nk.signal_simulate(duration=6,frequency=1)# Distort the signal (add noise, linear trend, artifacts, etc.)distorted=nk.signal_distort(original,noise_amplitude=0.1,noise_frequency=[5,10,20],powerline_amplitude=0.05,artifacts_amplitude=0.3,artifacts_number=3,linear_drift=0.5)# Clean (filter and detrend)cleaned=nk.signal_detrend(distorted)cleaned=nk.signal_filter(cleaned,lowcut=0.5,highcut=1.5)# Compare the 3 signalsplot=nk.signal_plot([original,distorted,cleaned])Complexity (Entropy, Fractal Dimensions, …)Optimize complexity parameters(delaytau, dimensionm, tolerancer)# Generate signalsignal=nk.signal_simulate(frequency=[1,3],noise=0.01,sampling_rate=200)# Find optimal time delay, embedding dimension, and rparameters=nk.complexity_optimize(signal,show=True)Compute complexity featuresEntropy: Sample Entropy (SampEn), Approximate Entropy (ApEn), Fuzzy Entropy (FuzzEn), Multiscale Entropy (MSE), Shannon Entropy (ShEn)Fractal dimensions: Correlation Dimension D2, …Detrended Fluctuation Analysisnk.entropy_sample(signal)nk.entropy_approximate(signal)Signal Decomposition# Create complex signalsignal=nk.signal_simulate(duration=10,frequency=1)# High freqsignal+=3*nk.signal_simulate(duration=10,frequency=3)# Higher freqsignal+=3*np.linspace(0,2,len(signal))# Add baseline and linear trendsignal+=2*nk.signal_simulate(duration=10,frequency=0.1,noise=0)# Non-linear trendsignal+=np.random.normal(0,0.02,len(signal))# Add noise# Decompose signal using Empirical Mode Decomposition (EMD)components=nk.signal_decompose(signal,method='emd')nk.signal_plot(components)# Visualize components# Recompose merging correlated componentsrecomposed=nk.signal_recompose(components,threshold=0.99)nk.signal_plot(recomposed)# Visualize componentsSignal Power Spectrum Density (PSD)# Generate complex signalsignal=nk.signal_simulate(duration=20,frequency=[0.5,5,10,15],amplitude=[2,1.5,0.5,0.3],noise=0.025)# Get the PSD using different methodswelch=nk.signal_psd(signal,method="welch",min_frequency=1,max_frequency=20,show=True)multitaper=nk.signal_psd(signal,method="multitapers",max_frequency=20,show=True)lomb=nk.signal_psd(signal,method="lomb",min_frequency=1,max_frequency=20,show=True)burg=nk.signal_psd(signal,method="burg",min_frequency=1,max_frequency=20,order=10,show=True)StatisticsHighest Density Interval (HDI)x=np.random.normal(loc=0,scale=1,size=100000)ci_min,ci_max=nk.hdi(x,ci=0.95,show=True)PopularityNeuroKit2 is one of the most welcoming packages for new contributors and users, as well as the fastest-growing package. So stop hesitating and hop on board 🤗Used atDisclaimerThe authors do not provide any warranty. If this software causes your keyboard to blow up, your brain to liquefy, your toilet to clog or a zombie plague to break loose, the authors CANNOT IN ANY WAY be held responsible.News0.2.4Fixeseda_sympathetic()has been reviewed: low-pass filter and resampling have been added to be in
line with the original papereda_findpeaks()using methods proposed in nabian2018 is reviewed and improved. Differentiation
has been added before smoothing. Skin conductance response criteria have been revised based on
the original paper.0.2.1New FeaturesAllow for input with NaNs and extrapolation insignal_interpolate()Add argumentmethodinfind_outliers()A lot (seehttps://github.com/neuropsychology/NeuroKit/pull/645)0.2.0New FeaturesAdd new time-domain measures inhrv_time():Prc20NN,Prc80NN,MinNN, andMaxNN0.1.6Breaking ChangesArgumenttypechanged tooutinexpspace()New FeaturesAdd new time-domain measures inhrv_time():Prc20NN,Prc80NN,MinNN, andMaxNNAllowfix_peaks()to account for larger intervalsFixes0.1.5Breaking ChangesArgumentrchanged toradiusinfractal_correlation()Argumentrchanged totolerancein entropy and complexity utility functionsArgumentr_methodchanged totolerance_methodincomplexity_optimize()complexity_lempelziv(),fractal_higuchi(),fractal_katz(),fractal_correlation(),fractal_dfa(),entropy_multiscale(),entropy_shannon(),entropy_approximate(),entropy_fuzzy(),entropy_sample()now return a tuple consisting of the complexity index, and a dictionary comprising of the different parameters specific to the measure. Forfractal_katz()andentropy_shannon(), the parameters dictionary is empty.Restructurecomplexitysubmodules with optimization files starting withoptim_*, such asoptim_complexity_delay(),optim_complexity_dimension(),optim_complexity_k(),optim_complexity_optimize(), andoptim_complexity_tolerance().mutual_information()moved fromstatsmodule tocomplexitymodule.New FeaturesAdded various complexity indices:complexity_hjorth(),complexity_hurst(),complexity_lyapunov(),complexity_rqa(),complexity_rr(),entropy_coalition(),entropy_permutation(),entropy_range(),entropy_spectral(),fractal_nld(),fractal_psdslope(),fractal_sda(),fractal_sevcik()Addedmne_templateMRI()as a helper to get MNE’s template MRI.Addedeeg_source()as a helper to perform source reconstruction.Addedeeg_source_extract()to extract the activity from a brain region.Addedparallel_run()inmiscas a parallel processing utility function.Addedfind_plateau()inmiscto find the point of plateau in an array of values.Addedwrite_csv()indatato facilitate saving dataframes into multiple parts.Added more complexity-related functions,entropy_cumulative_residual(),entropy_differential(),entropy_svd(),fractal_petrosian(), andinformation_fisher().Updates logic to findkmaxinfractal_higuchi()Add RSP_Amplitude_Baseline in event-related analysisAdd argumentadd_firstsamplesinmne_channel_extract()to account for first sample attribute in mne raw objectsAllow plotting ofmne.Epochsinepochs_plot()Addmne_crop()to cropmneRaw objects with additional flexibility to specify first and last elementsPlotting function ineeg_badchannels()to visualize overlay of individual EEG channels and highlighting of bad onesAddeog_peaks()as wrapper foreog_findpeaks()Allowecg_delineate()to account for different heart rateFixesEnsure detected offset inemg_activation()is not beyond signal lengthRaise ValueError in_hrv_sanitize_input()if RRIs are detected instead of peaksEnsure that multifractal DFA indices returned byfractal_mdfa()is not Nan when array of slopes contains Nan (due to zero fluctuations)Documentation of respiration from peak/trough terminology to inhale/exhale onsetsChange labelling inrsp_plot()from “inhalation peaks” and “exhalation troughs” to “peaks (exhalation onsets)” and “troughs (inhalation onsets)” respectively.Change RSP_Amplitude_Mean/Min/Max parameters to be corrected based on value closest to t=0 in event-related analysis, rather than using all pre-zero values.Haversp_rrv()compute breath-to-breath intervals based on trough indices (inhalation onsets) rather than peak indicesComputersp_rate()based on trough indices (rather than peak indices) in ‘periods’ method0.1.4.1FixesAdjustkmaxparameter infractal_higuchi()according to signal length as havingkmaxmore than half of signal length leads to division by zero errorEnsure that sanitization of input in_hrv_dfa()is done before windows forDFA_alpha2is computednp.seterris added tofractal_dfa()to avoid returning division by zero warning which is an expected behaviour0.1.4Breaking Changesfractal_df()now returns a dictionary of windows, fluctuations and the slope value (see documentation for more information. Ifmultifractalis True, the dictionary additionally contains the parameters of the singularity spectrum (seesingularity_spectrum()for more information)New FeaturesAdd convenience functionintervals_to_peaks()useful for RRI or BBI conversion to peak indiceshrv_nonlinear()andrrv_rsp()now return the parameters of singularity spectrum for multifractal DFA analysisAdd new complexity measures infractal_higuchi(),fractal_katz()andfractal_lempelziv()Add new time-domain measures inhrv_time():SDANNandSDNNIAdd new non-linear measures inhrv_nonlinear():ShanEn,FuzzyEn,HFD,KFDandLZCFixesAdd path argument inmne_data()and throw warning to download mne datasets if data folder is not presentThe implementation ofTTINinhrv_time()is amended to its correct formulation.The default binsize used for RRI histogram in the computation of geometric HRV indices is set to 1 / 128 seconds0.1.3Breaking ChangesNoneNew FeaturesAdd internal function for detecting missing data points and forward filling missing values innk.*_clean()functionsAdd computation of standard deviation ineventrelated()functions forECG_Rate_SD,EMG_Amplitude_SD,EOG_Rate_SD,PPG_Rate_SD,RSP_Rate_SD,RSP_Amplitude_SDAdd labelling for interval related features if a dictionary of dataframes is passedRetrun Q peaks and S Peaks information for wavelet-based methods innk.ecg_delineate()FixesFix epochs columns withdtype: objectgenerated bynk.epochs_create()Bug fix ecg_findpeaks_rodrigues for array out of bounds bug0.1.2New FeaturesAdditional features fornk.rsp_intervalrelated(): average inspiratory and expiratory durations, inspiratory-to-expiratory (I/E) time ratioAdd multiscale entropy measures (MSE, CMSE, RCMSE) and fractal methods (Detrended Fluctuation Analysis, Correlation Dimension) intonk.hrv_nonlinear()Allow for data resampling innk.read_bitalino()Addbio_resting_8min_200hzinto database for reading withnk.data()Reading of url links innk.data()Allow fornk.hrv()to compute RSA indices if respiratory data is presentAllhrvfunctions to automatically detect correct sampling rate if tuple or dict is passed as inputAdd support for PPG analysis:nk.ppg_eventrelated(),nk.ppg_intervalrelated(),nk.ppg_analyze()Add Zhao et al. (2018) method fornk.ecg_quality()Add tests forepochsmoduleAdd sub-epoch option for ECG and RSP event-related analysis:users can create a smaller sub-epoch within the event-related epochthe rate-related features of ECG and RSP signals are calculated over the sub-epochthe remaining features are calculated over the original epoch, not the sub-epochFixesFix propagation of values innk.signal_formatpeaks()for formatting SCR column outputs generated byeda_peaks()Fix docstrings ofnk.rsp_phase(), from “RSP_Inspiration” to “RSP_Phase”Updatesignal_filter()method forrsp_clean(): to usesosform, instead ofbaform of butterworth (similar toeda_clean())0.1.1New FeaturesUse duration fromnk.events_find()asepochs_endinnk.epochs_create()Allow customized subsets of epoch lengths innk.bio_analyze()withwindow_lengthsargumentAddnk.find_outliers()to identify outliers (abnormal values)Add utility function -nk.check_type()to return appropriate boolean values of input (integer, list, ndarray, pandas dataframe or pandas series)(experimental) Add error bars in the summary plot method to illustrate standard error of each binFixesFix type of value innk.signal_formatpeaks()to ensure slice assignment is done on the same type0.0.1 (2019-10-29)First release on PyPI.