Source code for neurokit2.complexity.entropy_grid

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from .entropy_shannon import entropy_shannon


[docs] def entropy_grid(signal, delay=1, k=3, show=False, **kwargs): """**Grid Entropy (GridEn)** Grid Entropy (GridEn or GDEn) is defined as a gridded descriptor of a :func:`Poincaré plot <.hrv_nonlinear>`, which is a two-dimensional phase space diagram of a time series that plots the present sample of a time series with respect to their delayed values. The plot is divided into :math:`n*n` grids, and the :func:`Shannon entropy <entropy_shannon>` is computed from the probability distribution of the number of points in each grid. Yan et al. (2019) define two novel measures, namely **GridEn** and **Gridded Distribution Rate (GDR)**, the latter being the percentage of grids containing points. Parameters ---------- signal : Union[list, np.array, pd.Series] The signal (i.e., a time series) in the form of a vector of values. delay : int Time delay (often denoted *Tau* :math:`\\tau`, sometimes referred to as *lag*) in samples. See :func:`complexity_delay` to estimate the optimal value for this parameter. k : int The number of sections that the Poincaré plot is divided into. It is a coarse graining parameter that defines how fine the grid is. show : bool Plot the Poincaré plot. **kwargs : optional Other keyword arguments, such as the logarithmic ``base`` to use for :func:`entropy_shannon`. Returns ------- griden : float Grid Entropy of the signal. info : dict A dictionary containing additional information regarding the parameters used. See Also -------- entropy_shannon, .hrv_nonlinear, entropy_phase Examples ---------- .. ipython:: python import neurokit2 as nk # Simulate a Signal signal = nk.signal_simulate(duration=2, sampling_rate=200, frequency=[5, 6], noise=0.5) # Compute Grid Entropy @savefig p_entropy_grid1.png scale=100% phasen, info = nk.entropy_grid(signal, k=3, show=True) @suppress plt.close() .. ipython:: python phasen @savefig p_entropy_grid2.png scale=100% phasen, info = nk.entropy_grid(signal, k=10, show=True) @suppress plt.close() .. ipython:: python info["GDR"] References ---------- * Yan, C., Li, P., Liu, C., Wang, X., Yin, C., & Yao, L. (2019). Novel gridded descriptors of poincaré plot for analyzing heartbeat interval time-series. Computers in biology and medicine, 109, 280-289. """ # Sanity checks if isinstance(signal, (np.ndarray, pd.DataFrame)) and signal.ndim > 1: raise ValueError( "Multidimensional inputs (e.g., matrices or multichannel data) are not supported yet." ) info = {"k": k, "Delay": delay} # Normalization Sig_n = (signal - min(signal)) / np.ptp(signal) # Poincaré Plot Temp = np.array([Sig_n[:-delay], Sig_n[delay:]]) # Get count of points in each grid hist, _, _ = np.histogram2d(Temp[0, :], Temp[1, :], k) # Get frequency freq = np.flipud(hist.T) / hist.sum() freq = freq[freq > 0] # Compute Shannon Entropy griden, _ = entropy_shannon(freq=freq, **kwargs) # Compute Gridded Distribution Rate info["GDR"] = np.sum(hist != 0) / hist.size if show is True: gridlines = np.linspace(0, 1, k + 1) plt.subplots(1, 2) x1 = plt.subplot(121) ax1 = plt.axes(x1) ax1.plot(Sig_n[:-delay], Sig_n[delay:], ".", color="#009688") ax1.plot( np.tile(gridlines, (2, 1)), np.array((np.zeros(k + 1), np.ones(k + 1))), color="red", ) ax1.plot( np.array((np.zeros(k + 1), np.ones(k + 1))), np.tile(gridlines, (2, 1)), color="red", ) ax1.plot([0, 1], [0, 1], "k") ax1.set_aspect("equal", "box") ax1.set_xlabel(r"$X_{i}$") ax1.set_ylabel(r"$X_{i} + \tau$") ax1.set_xticks([0, 1]) ax1.set_yticks([0, 1]) ax1.set_xlim([0, 1]) ax1.set_ylim([0, 1]) x2 = plt.subplot(122) ax2 = plt.axes(x2) ax2.imshow(np.fliplr(hist), cmap="rainbow", aspect="equal") ax1.set_xlabel(r"$X_{i}$") ax1.set_ylabel(r"$X_{i} + \tau$") ax2.set_xticks([]) ax2.set_yticks([]) plt.suptitle("Gridded Poincaré Plot and its Density") return griden, info