Source code for neurokit2.eda.eda_plot

# -*- coding: utf-8 -*-
import matplotlib.collections
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from ..misc import find_closest


[docs]def eda_plot(eda_signals, sampling_rate=None): """Visualize electrodermal activity (EDA) data. Parameters ---------- eda_signals : DataFrame DataFrame obtained from `eda_process()`. sampling_rate : int The desired sampling rate (in Hz, i.e., samples/second). Defaults to None. Returns ------- fig Figure representing a plot of the processed EDA signals. Examples -------- >>> import neurokit2 as nk >>> >>> eda_signal = nk.eda_simulate(duration=30, scr_number=5, drift=0.1, noise=0, sampling_rate=250) >>> eda_signals, info = nk.eda_process(eda_signal, sampling_rate=250) >>> fig = nk.eda_plot(eda_signals) >>> fig #doctest: +SKIP See Also -------- eda_process """ # Determine peaks, onsets, and half recovery. peaks = np.where(eda_signals["SCR_Peaks"] == 1)[0] onsets = np.where(eda_signals["SCR_Onsets"] == 1)[0] half_recovery = np.where(eda_signals["SCR_Recovery"] == 1)[0] fig, (ax0, ax1, ax2) = plt.subplots(nrows=3, ncols=1, sharex=True) # Determine unit of x-axis. last_ax = fig.get_axes()[-1] if sampling_rate is not None: last_ax.set_xlabel("Seconds") x_axis = np.linspace(0, len(eda_signals) / sampling_rate, len(eda_signals)) else: last_ax.set_xlabel("Samples") x_axis = np.arange(0, len(eda_signals)) plt.subplots_adjust(hspace=0.2) # Plot cleaned and raw respiration as well as peaks and troughs. ax0.set_title("Raw and Cleaned Signal") fig.suptitle("Electrodermal Activity (EDA)", fontweight="bold") ax0.plot(x_axis, eda_signals["EDA_Raw"], color="#B0BEC5", label="Raw", zorder=1) ax0.plot(x_axis, eda_signals["EDA_Clean"], color="#9C27B0", label="Cleaned", linewidth=1.5, zorder=1) ax0.legend(loc="upper right") # Plot skin cnoductance response. ax1.set_title("Skin Conductance Response (SCR)") # Plot Phasic. ax1.plot(x_axis, eda_signals["EDA_Phasic"], color="#E91E63", label="Phasic Component", linewidth=1.5, zorder=1) # Mark segments. risetime_coord, amplitude_coord, halfr_coord = _eda_plot_dashedsegments( eda_signals, ax1, x_axis, onsets, peaks, half_recovery ) risetime = matplotlib.collections.LineCollection(risetime_coord, colors="#FFA726", linewidths=1, linestyle="dashed") ax1.add_collection(risetime) amplitude = matplotlib.collections.LineCollection( amplitude_coord, colors="#1976D2", linewidths=1, linestyle="solid" ) ax1.add_collection(amplitude) halfr = matplotlib.collections.LineCollection(halfr_coord, colors="#FDD835", linewidths=1, linestyle="dashed") ax1.add_collection(halfr) ax1.legend(loc="upper right") # Plot Tonic. ax2.set_title("Skin Conductance Level (SCL)") ax2.plot(x_axis, eda_signals["EDA_Tonic"], color="#673AB7", label="Tonic Component", linewidth=1.5) ax2.legend(loc="upper right") plt.show() return fig
# ============================================================================= # Internals # ============================================================================= def _eda_plot_dashedsegments(eda_signals, ax, x_axis, onsets, peaks, half_recovery): # Mark onsets, peaks, and half-recovery. scat_onset = ax.scatter( x_axis[onsets], eda_signals["EDA_Phasic"][onsets], color="#FFA726", label="SCR - Onsets", zorder=2 ) scat_peak = ax.scatter( x_axis[peaks], eda_signals["EDA_Phasic"][peaks], color="#1976D2", label="SCR - Peaks", zorder=2 ) scat_halfr = ax.scatter( x_axis[half_recovery], eda_signals["EDA_Phasic"][half_recovery], color="#FDD835", label="SCR - Half recovery", zorder=2, ) end_onset = pd.Series(eda_signals["EDA_Phasic"][onsets].values, eda_signals["EDA_Phasic"][peaks].index) scat_endonset = ax.scatter(x_axis[end_onset.index], end_onset.values, alpha=0) # Rise time. risetime_start = scat_onset.get_offsets() risetime_end = scat_endonset.get_offsets() risetime_coord = [(risetime_start[i], risetime_end[i]) for i in range(0, len(onsets))] # SCR Amplitude. peak_top = scat_peak.get_offsets() amplitude_coord = [(peak_top[i], risetime_end[i]) for i in range(0, len(onsets))] # Half recovery. peak_x_values = peak_top.data[:, 0] recovery_x_values = x_axis[half_recovery] peak_list = [] for i, index in enumerate(half_recovery): value = find_closest(recovery_x_values[i], peak_x_values, direction="smaller", strictly=False) peak_list.append(value) peak_index = [] for i in np.array(peak_list): index = np.where(i == peak_x_values)[0][0] peak_index.append(index) halfr_index = list(range(0, len(half_recovery))) halfr_end = scat_halfr.get_offsets() halfr_start = [(peak_top[i, 0], halfr_end[x, 1]) for i, x in zip(peak_index, halfr_index)] halfr_coord = [(halfr_start[i], halfr_end[i]) for i in halfr_index] return risetime_coord, amplitude_coord, halfr_coord