Source code for app.mimic3bp_data_visualization

"""
File: app/mimic3bp_data_visualization.py
Project: 22HLT01 QUMPHY
Contact: nando.hegemann@ptb.de
Gitlab: https://gitlab.com/qumphy
Description: Create images of samples from MIMIC III BP dataset.
"""

import os
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from tqdm.auto import tqdm
import qumphy  # local import


[docs] def normalize_signals(signals: np.ndarray) -> np.ndarray: """Normalize signal data to [0, 1]. Parameters ---------- signals : np.ndarray Signal array. Returns ------- : Normalized signal array. """ shift = np.min(signals, axis=1).reshape(-1, 1) scale = 1 / (np.max(signals, axis=1).reshape(-1, 1) - shift) return scale * (signals - shift)
[docs] def plot_signal_grid( labels: np.ndarray, signals: np.ndarray, subject_ids: np.ndarray, tag: str, save_path: str, dpi: int = 300, ) -> None: """Save a 6x6 grid of randomly sampled PPG signals colored by blood pressure. Inner line color encodes systolic BP, outer line color encodes diastolic BP. Parameters ---------- labels : np.ndarray Systolic/diastolic blood pressure values, shape ``(n_samples, 2)``. signals : np.ndarray PPG time series. subject_ids : np.ndarray Subject IDs. tag : str Filename stem and figure title suffix. save_path : str Directory the ``<tag>.png`` image is written to. dpi : int, optional Resolution of image, by default 300. """ cmap = matplotlib.cm.get_cmap("rainbow", 8) cmin = np.array([40, 40]) cmax = np.array([200, 120]) scale = 1 / (cmax - cmin) n_rows, n_cols = 6, 6 idxs = np.random.randint(labels.shape[0], size=(n_rows, n_cols)) # create plot layout = [[f"{i}-{j}" for j in range(n_cols)] + ["cmap1"] for i in range(n_rows)] for i in range(n_rows): for j in range(n_cols): if i <= 1 and j >= n_cols - 3: layout[i][j] = "big" fig, ax = plt.subplot_mosaic( layout, constrained_layout=True, figsize=(3 * n_cols + 6, 2 * n_rows) ) for i in range(n_rows): for j in range(n_cols): if i > 1 or j < n_cols - 3: label = labels[idxs[i, j]] signal = signals[idxs[i, j]] sid = subject_ids[idxs[i, j]] color = cmap(scale * (label - cmin)) ax[f"{i}-{j}"].plot(signal, color=color[1], lw=3) ax[f"{i}-{j}"].plot(signal, color=color[0], lw=1) ax[f"{i}-{j}"].set_axis_off() ax[f"{i}-{j}"].set_title(f"subject id: {sid}") label = labels[idxs[0, n_cols - 1]] signal = signals[idxs[0, n_cols - 1]] sid = subject_ids[idxs[0, n_cols - 1]] color = cmap(scale * (label - cmin)) ax["big"].plot(signal, color=color[1], lw=9) ax["big"].plot(signal, color=color[0], lw=3) ax["big"].set_axis_off() ax["big"].set_title(f"subject id: {sid}") norm1 = matplotlib.colors.Normalize(vmin=cmin[0], vmax=cmax[0]) norm2 = matplotlib.colors.Normalize(vmin=cmin[1], vmax=cmax[1]) ax["cmap1"].set_axis_off() fig.colorbar( matplotlib.cm.ScalarMappable(norm=norm1, cmap=cmap), ax=ax["cmap1"], label="systolic BP [mmHg]", pad=-0.85, fraction=0.5, ) fig.colorbar( matplotlib.cm.ScalarMappable(norm=norm2, cmap=cmap), ax=ax["cmap1"], orientation="vertical", label="diastolic BP [mmHg]", pad=-0.4, fraction=0.5, ) plt.suptitle( "MIMIC III BP formatted" + f" -- {tag}" + " -- systolic BP = innter color" + " -- diastolic BP = outer color", fontsize=30, ) plt.savefig(save_path + tag + ".png", dpi=dpi) plt.close()
[docs] def main() -> None: """Render one PNG grid per MIMIC III BP split into ``../img/mimic3bp/``.""" # load data data_path = "../data/mimic3bp/" save_path = "../img/mimic3bp/" os.makedirs(save_path, exist_ok=True) file_ids = ["test", "validate"] + [f"train{j+1:02d}" for j in range(28)] for fid in tqdm(file_ids): labels, signals, subject_ids = qumphy.data.mimic3bp.load(fid, data_path) signals = normalize_signals(signals) # add samples of training data to tensorboard plot_signal_grid( labels, signals, subject_ids, tag=fid, save_path=save_path, dpi=300 ) del labels, signals, subject_ids
if __name__ == "__main__": main()