8.1 Anomaly detection in timeseries of networks

8.1 Anomaly detection in timeseries of networks#

mode = "svg"

import matplotlib

font = {'family' : 'Dejavu Sans',
        'weight' : 'normal',
        'size'   : 20}

matplotlib.rc('font', **font)

import matplotlib
from matplotlib import pyplot as plt
import numpy as np
from graspologic.simulations import sbm
from graphbook_code import dcsbm

np.random.seed(2)

# the block matrix for the neurons before learning
B0 = 0.05*np.ones((3, 3))
np.fill_diagonal(B0, 0.4)

nk = 40
ns = np.repeat(nk, 3)

theta = np.tile(np.linspace(np.sqrt(2), np.sqrt(2) - 1, nk), 3)
zs = np.repeat([1,2,3], nk)

T = 12
networks = np.array([sbm(ns, B0) if (t < 6 or t >= 9) else dcsbm(zs, theta, B0) for t in range(T)])
from graphbook_code import heatmap
import seaborn as sns
import os

def add_border(ax, **kwargs):
    sns.despine(ax=ax, **kwargs)

# Create the combined figure
fig_combined = plt.figure(figsize=(20, 5))

for i in range(6):
    ax = fig_combined.add_axes([0.01 * i + 0.00, -0.02 * i, 0.13, 0.8])
    if i == 0:
        ylab = "Brain area"
    else:
        ylab = ""
    if i == 5:
        xlab = "Brain area"
    else:
        xlab = ""
    heatmap(networks[i].astype(int), ax=ax, xtitle=xlab, ytitle=ylab, cbar=False)
    if i == 0:
        ax.set_title("(A) Six timepoints before learning", loc="left", fontsize=16)
    add_border(ax, top=False, right=False)

# Add the axes from fig2
for i in range(3):
    ax = fig_combined.add_axes([0.01 * i + 0.27, -0.02 * i, 0.13, 0.8])
    if i == 0:
        ylab = "Brain area"
    else:
        ylab = ""
    if i == 2:
        xlab = "Brain area"
    else:
        xlab = ""
    heatmap(networks[i + 6].astype(int), ax=ax, xtitle=xlab, ytitle=ylab, cbar=False)
    if i == 0:
        ax.set_title("(B) Three timepoints after learning", loc="left", fontsize=16)
    add_border(ax, top=False, right=False)

# Add the axes from fig3
for i in range(3):
    ax = fig_combined.add_axes([0.01 * i + 0.5, -0.02 * i, 0.13, 0.8])
    if i == 0:
        ylab = "Brain area"
    else:
        ylab = ""
    if i == 2:
        xlab = "Brain area"
    else:
        xlab = ""
    heatmap(networks[i + 9].astype(int), ax=ax, xtitle=xlab, ytitle=ylab, cbar=False)
    if i == 0:
        ax.set_title("(C) Three timepoints after shock", loc="left", fontsize=16)
    add_border(ax, top=False, right=False)

fig_combined.tight_layout(rect=[0,0, 1, .95])

os.makedirs("Figures", exist_ok=True)
fname = "anom_ex"
if mode != "png":
    os.makedirs(f"Figures/{mode:s}", exist_ok=True)
    fig_combined.savefig(f"Figures/{mode:s}/{fname:s}.{mode:s}", bbox_inches='tight')

os.makedirs("Figures/png", exist_ok=True)
fig_combined.savefig(f"Figures/png/{fname:s}.png", bbox_inches='tight')
/tmp/ipykernel_2700/3431049457.py:58: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  fig_combined.tight_layout(rect=[0,0, 1, .95])
../../_images/04c1f21ab9c0078d8d40199bb30dadee98ec252566525255a534cedd5b1d6b6d.png
from graspologic.inference import latent_position_test
import warnings

warnings.filterwarnings('ignore')
pvalues = [latent_position_test(networks[t + 1], networks[t], n_components=3,
                                n_bootstraps=1000, workers=-1)[1] for t in range(T-1)]
from statsmodels.stats.multitest import multipletests

alpha = 0.05
_, adj_pvals, _, _ = multipletests(pvalues, alpha=alpha, method="holm")
from graphbook_code import lpm_heatmap

fig, ax = plt.subplots(1, 1, figsize=(15, 3))

lpm_heatmap(adj_pvals.reshape(1, -1), title="Corrected $p$-value for test of anomalies from one timepoint to next",
            ax = ax, xtitle="Timepoint Comparison", annot=True, vmin=0, vmax=1, cbar=False,
           xticklabels=[f"{i+1:d}:{i+2:d}" for i in range(0, T-1)])

fig.tight_layout()

fname = "anom_pvals"
if mode != "png":
    fig.savefig(f"Figures/{mode:s}/{fname:s}.{mode:s}")

fig.savefig(f"Figures/png/{fname:s}.png")
../../_images/dce6f32c10b1e0af311a298460dd775abcbf97e468812cc19230225be820edb5.png