Analysis of L2-regularization on the mouse brain dataset

[1]:
import pandas as pd
import numpy as np
import scanpy as sc
import anndata as ad
import os

import warnings
warnings.filterwarnings("ignore")

os.environ["CUDA_VISIBLE_DEVICES"] = "0"

import sys
sys.path.append(r'/import/home2/share/yqzeng/MacSGP/codes')
import MacSGP
[2]:
DATA_PATH = "/import/home2/share/yqzeng/MacSGP/data/Mouth_brain_visium" # Raw data
SAVE_PATH = "/import/home2/share/yqzeng/MacSGP/Results/Mouth_brain_visium" # Deconvolution results
os.makedirs(os.path.join(SAVE_PATH), exist_ok = True)
[7]:
adata_st = ad.read_h5ad(os.path.join(DATA_PATH, "visium_1.h5ad"))
adata_basis = ad.read_h5ad(os.path.join(DATA_PATH, "visium_1_basis.h5ad"))
[16]:
model = MacSGP.model.Model(adata_st, adata_basis, n_layers=4, training_steps=6000, coef_reg=0.05)

model.train(step_interval=300, reg_mode="L1")
adata_result = model.eval()
  0%|          | 2/6000 [00:00<16:53,  5.92it/s]
Step: 0, Loss: -5790.5874, d_loss: -5795.3467, f_loss: 47.3751, reg_loss: 0.0471
  5%|▌         | 302/6000 [00:50<16:02,  5.92it/s]
Step: 300, Loss: -6015.6699, d_loss: -6019.5962, f_loss: 23.1051, reg_loss: 3.4936
 10%|█         | 602/6000 [01:41<15:10,  5.93it/s]
Step: 600, Loss: -6065.7979, d_loss: -6070.0459, f_loss: 22.0375, reg_loss: 4.4207
 15%|█▌        | 902/6000 [02:32<14:22,  5.91it/s]
Step: 900, Loss: -6086.4326, d_loss: -6091.0820, f_loss: 21.7001, reg_loss: 5.3608
 20%|██        | 1202/6000 [03:22<13:32,  5.91it/s]
Step: 1200, Loss: -6095.9038, d_loss: -6100.5137, f_loss: 21.4998, reg_loss: 5.3190
 25%|██▌       | 1502/6000 [04:13<12:42,  5.90it/s]
Step: 1500, Loss: -6104.2290, d_loss: -6109.1055, f_loss: 21.3814, reg_loss: 5.9206
 30%|███       | 1802/6000 [05:04<11:51,  5.90it/s]
Step: 1800, Loss: -6109.9336, d_loss: -6114.9810, f_loss: 21.2735, reg_loss: 6.3137
 35%|███▌      | 2102/6000 [05:55<10:59,  5.91it/s]
Step: 2100, Loss: -6115.6611, d_loss: -6121.0566, f_loss: 21.1849, reg_loss: 7.0851
 40%|████      | 2402/6000 [06:45<10:09,  5.90it/s]
Step: 2400, Loss: -6120.3560, d_loss: -6125.9858, f_loss: 21.1062, reg_loss: 7.6090
 45%|████▌     | 2702/6000 [07:36<09:19,  5.90it/s]
Step: 2700, Loss: -6122.8345, d_loss: -6128.3804, f_loss: 21.0296, reg_loss: 7.4444
 50%|█████     | 3002/6000 [08:27<08:28,  5.89it/s]
Step: 3000, Loss: -6124.8662, d_loss: -6130.5376, f_loss: 20.9629, reg_loss: 7.7299
 55%|█████▌    | 3302/6000 [09:18<07:37,  5.90it/s]
Step: 3300, Loss: -6126.4736, d_loss: -6132.1743, f_loss: 20.9071, reg_loss: 7.8053
 60%|██████    | 3602/6000 [10:08<06:46,  5.91it/s]
Step: 3600, Loss: -6128.7339, d_loss: -6134.6445, f_loss: 20.8606, reg_loss: 8.2694
 65%|██████▌   | 3902/6000 [10:59<05:55,  5.90it/s]
Step: 3900, Loss: -6130.4492, d_loss: -6136.3662, f_loss: 20.8028, reg_loss: 8.2963
 70%|███████   | 4202/6000 [11:50<05:04,  5.91it/s]
Step: 4200, Loss: -6131.2261, d_loss: -6137.1187, f_loss: 20.7844, reg_loss: 8.2464
 75%|███████▌  | 4502/6000 [12:40<04:13,  5.91it/s]
Step: 4500, Loss: -6131.9092, d_loss: -6137.7905, f_loss: 20.7220, reg_loss: 8.2359
 80%|████████  | 4802/6000 [13:31<03:22,  5.91it/s]
Step: 4800, Loss: -6132.3647, d_loss: -6138.2515, f_loss: 20.6877, reg_loss: 8.2551
 85%|████████▌ | 5102/6000 [14:22<02:32,  5.90it/s]
Step: 5100, Loss: -6132.9199, d_loss: -6138.7715, f_loss: 20.6516, reg_loss: 8.1872
 90%|█████████ | 5402/6000 [15:12<01:41,  5.91it/s]
Step: 5400, Loss: -6133.5044, d_loss: -6139.3950, f_loss: 20.6207, reg_loss: 8.2782
 95%|█████████▌| 5702/6000 [16:03<00:50,  5.91it/s]
Step: 5700, Loss: -6134.7549, d_loss: -6140.8169, f_loss: 20.5936, reg_loss: 8.6543
100%|██████████| 6000/6000 [16:53<00:00,  5.92it/s]
[20]:
adata_result.write_h5ad(os.path.join(SAVE_PATH, "visium_1_result_l1_0.05.h5ad"))
[3]:
adata_result = sc.read_h5ad(os.path.join(SAVE_PATH, "visium_1_result_l1_0.05.h5ad"))
[17]:

ct_plot = ['Astro_HPC','Astro_HYPO','Ext_Amy_2','Ext_Hpc_CA1','Ext_Hpc_CA3','Ext_Hpc_DG1', 'Ext_L23','Ext_L5_1','Ext_L5_2','Ext_L6','Ext_Med','Ext_Pir','Ext_Thal_1','Ext_Thal_2','Inh_1','Inh_3','Inh_4','Inh_Meis2_3','Oligo_1','Oligo_2'] from MacSGP.vis import plot_spatial_ct plot_spatial_ct(adata_result, index='factor', celltype_plot=ct_plot, proportion_threshold=0.0, num_threshold=100, cmap='coolwarm', spot_size=100, ncols=6)
Dropping cell types: []
../../_images/analysis_mouse_brain_mouse_brain_reg_7_1.png
[ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from itertools import combinations
from scipy.stats import pearsonr
from libpysal.weights import KNN
import matplotlib as mpl

mpl.rcParams.update({
    'font.family': 'Helvetica',
    'font.size': 7,
    'axes.titlesize': 8,
    'axes.labelsize': 7,
    'xtick.labelsize': 6.5,
    'ytick.labelsize': 6.5,
    'axes.linewidth': 0.5,
    'xtick.major.width': 0.5,
    'ytick.major.width': 0.5,
    'xtick.major.size': 2.5,
    'ytick.major.size': 2.5,
    'pdf.fonttype': 42,
    'ps.fonttype': 42,
    'savefig.dpi': 300,
    'figure.dpi': 150,
})
[5]:
ct_plot = ['Ext_Med', 'Ext_Pir', 'Ext_Thal_1', 'Ext_Thal_2']
[ ]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator, FormatStrFormatter
loadings = adata_result.varm['loading'][ct_plot]
if hasattr(loadings, 'columns'):
    ct_names = list(loadings.columns)
    loadings = loadings.values
else:
    ct_names = [f'CT_{i}' for i in range(loadings.shape[1])]

n_ct = loadings.shape[1]
ncols = 4
nrows = int(np.ceil(n_ct / ncols))

#clip = np.percentile(np.abs(loadings), 99.5)

fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 3, nrows * 2.5))
axes = axes.flatten()
cmap = plt.cm.get_cmap('tab10', n_ct)

for i in range(n_ct):
    ax = axes[i]
    vec = loadings[:, i]
    #vec_clip = vec[(vec > -clip) & (vec < clip)]

    ax.hist(vec, bins=60, color=cmap(i), alpha=0.7, edgecolor='white', linewidth=0.3)
    ax.axvline(x=0, color='red', linestyle='--', alpha=0.5, linewidth=1)
    ax.set_yscale('function', functions=(np.sqrt, np.square))
    ax.set_title(ct_names[i], fontsize=15, fontweight='bold')
    #ax.set_xlim(-clip, clip)
    #if i >= ncols:
    ax.set_xlabel('Loading weight', fontsize=15)
    if i % ncols == 0:
        ax.set_ylabel('Gene count', fontsize=15)
    ax.tick_params(labelsize=7, )
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    if ct_names[i] in ['Ext_Med', 'Ext_Thal_2']:
        ax.xaxis.set_major_locator(MaxNLocator(nbins=4))
        ax.xaxis.set_major_formatter(FormatStrFormatter('%.4f'))

for j in range(n_ct, len(axes)):
    axes[j].set_visible(False)

#fig.suptitle('Gene Loading Distribution per Cell Type', fontsize=13, fontweight='bold')
plt.tight_layout()
plt.show()
../../_images/analysis_mouse_brain_mouse_brain_reg_10_0.png
[8]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import TwoSlopeNorm
from matplotlib.ticker import MaxNLocator

factors = adata_result.obsm['factor']
ct_names = ct_plot
factor_mat = factors
spatial = adata_result.obsm['spatial']
x, y = spatial[:, 0], spatial[:, 1]

n_ct = len(ct_names)
ncols = 4
nrows = int(np.ceil(n_ct / ncols))

fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 3.5, nrows * 3.2))
axes = axes.flatten()

for i, ct in enumerate(ct_names):
    ax = axes[i]
    vec = factors[ct]
    vmax = np.percentile(np.abs(vec), 99)
    #norm = TwoSlopeNorm(vmin=-vmax, vcenter=0, vmax=vmax)
    norm = TwoSlopeNorm(vcenter=0)
    sc = ax.scatter(x, y, c=vec, cmap='coolwarm', norm=norm,
                    s=8, linewidths=0)#, rasterized=True)
    cb = fig.colorbar(sc, ax=ax, shrink=0.75, pad=0.02)
    cb.locator = MaxNLocator(nbins=5)
    cb.update_ticks()
    cb.ax.tick_params(labelsize=10)
    ax.set_title(ct, fontsize=15, fontweight='bold')
    ax.set_aspect('equal')
    ax.axis('off')

for j in range(n_ct, len(axes)):
    axes[j].set_visible(False)

#plt.suptitle('Spatial factor distribution per cell type', fontsize=13, fontweight='bold')
plt.tight_layout()
#plt.savefig('factor_spatial.pdf', dpi=300, bbox_inches='tight')
plt.show()
../../_images/analysis_mouse_brain_mouse_brain_reg_11_0.png
[27]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import TwoSlopeNorm
from matplotlib.ticker import MaxNLocator

factors = adata_result.obsm['proportion']
ct_names = ct_plot
factor_mat = factors
spatial = adata_result.obsm['spatial']
x, y = spatial[:, 0], spatial[:, 1]

n_ct = len(ct_names)
ncols = 4
nrows = int(np.ceil(n_ct / ncols))

fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 3.5, nrows * 3.2))
axes = axes.flatten()

for i, ct in enumerate(ct_names):
    ax = axes[i]
    vec = factors[ct]
    vmax = np.percentile(np.abs(vec), 99)
    #norm = TwoSlopeNorm(vmin=-vmax, vcenter=0, vmax=vmax)
    norm = TwoSlopeNorm(vcenter=0)
    sc = ax.scatter(x, y, c=vec, cmap='Reds', #norm=norm,
                    s=8, linewidths=0)#, rasterized=True)
    cb = fig.colorbar(sc, ax=ax, shrink=0.75, pad=0.02)
    cb.locator = MaxNLocator(nbins=5)
    cb.update_ticks()
    cb.ax.tick_params(labelsize=10)
    ax.set_title(ct, fontsize=20, fontweight='bold')
    ax.set_aspect('equal')
    ax.axis('off')

for j in range(n_ct, len(axes)):
    axes[j].set_visible(False)

#plt.suptitle('Spatial factor distribution per cell type', fontsize=13, fontweight='bold')
plt.tight_layout()
#plt.savefig('factor_spatial.pdf', dpi=300, bbox_inches='tight')
plt.show()
../../_images/analysis_mouse_brain_mouse_brain_reg_12_0.png
[26]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import TwoSlopeNorm
from matplotlib.ticker import MaxNLocator, FormatStrFormatter

ct_names = ct_plot   # ['Ext_Med', 'Ext_Pir', 'Ext_Thal_1', 'Ext_Thal_2']
n_ct = len(ct_names)
ncols = n_ct
nrows = 3

spatial = adata_result.obsm['spatial']
x, y = spatial[:, 0], spatial[:, 1]

proportions = adata_result.obsm['proportion']
factors     = adata_result.obsm['factor']
loadings    = adata_result.varm['loading'][ct_names].values

row_h = [2.2, 2.2, 1.8]
fig = plt.figure(figsize=(ncols * 2.6, sum(row_h)))
gs = fig.add_gridspec(nrows, ncols,
                      height_ratios=row_h,
                      hspace=0.05, wspace=0.15)

row_labels = ['Proportion', 'Factor', 'Gene weight']
cmap_tab = plt.cm.get_cmap('tab10', n_ct)

for row in range(nrows):
    for col, ct in enumerate(ct_names):
        ax = fig.add_subplot(gs[row, col])

        if row == 0:
            vec = proportions[ct]
            sc = ax.scatter(x, y, c=vec, cmap='Reds', s=4, linewidths=0)
            cb = fig.colorbar(sc, ax=ax, shrink=0.7, pad=0.02)
            cb.locator = MaxNLocator(nbins=3)
            cb.update_ticks()
            cb.ax.tick_params(labelsize=8)
            ax.set_aspect('equal')
            ax.axis('off')

        elif row == 1:
            vec = factors[ct]
            norm = TwoSlopeNorm(vcenter=0)
            sc = ax.scatter(x, y, c=vec, cmap='coolwarm', norm=norm,
                            s=4, linewidths=0)
            cb = fig.colorbar(sc, ax=ax, shrink=0.7, pad=0.02)
            cb.locator = MaxNLocator(nbins=3)
            cb.update_ticks()
            cb.ax.tick_params(labelsize=8)
            ax.set_aspect('equal')
            ax.axis('off')

        else:
            vec = loadings[:, col]
            ax.hist(vec, bins=60, color=cmap_tab(col),
                    alpha=0.75, edgecolor='white', linewidth=0.2)
            ax.axvline(x=0, color='red', linestyle='--', alpha=0.5, linewidth=0.8)
            ax.set_yscale('function', functions=(np.sqrt, np.square))
            ax.set_xlabel('Loading weight', fontsize=10)
            if col == 0:
                ax.set_ylabel('Gene count', fontsize=10)
            ax.tick_params(labelsize=7)
            ax.spines['top'].set_visible(False)
            ax.spines['right'].set_visible(False)

            if ct in ['Ext_Med', 'Ext_Thal_2']:
                ax.xaxis.set_major_locator(MaxNLocator(nbins=3))
                ax.xaxis.set_major_formatter(FormatStrFormatter('%.4f'))

        if row == 0:
            ax.set_title(ct, fontsize=11, fontweight='bold', pad=3)

        if col == 0:
            ax.annotate(row_labels[row],
                        xy=(-0.22, 0.5), xycoords='axes fraction',
                        fontsize=10, fontweight='bold',
                        ha='right', va='center', rotation=90)

plt.show()

../../_images/analysis_mouse_brain_mouse_brain_reg_13_0.png