SURFACE-Bind
  • Home
  • Analysis
  • Protein Families
    • Enzymes
    • Receptors
    • Transporters
    • Miscellaneous
    • Unclassified
    • Unmatched
  • About

On this page

  • Binding site distribution
  • Binding site histogram on main classes
  • Seed distribution in sub-families
  • Correlation between Area and Hydrophobicity of the binding sites for Sub-familes
  • Residue frequency in binding sites

General Analysis

Author

Hamed Khakzad

Published

August 9, 2024

  • Main families including: Transporters, Receptors, Enzymes, Unclassified, Miscellaneous, and Unmatched.

  • Sub-families including: SLC, GPCR, Channels, Hydrolases, Active_transporters, Kinase, Lyases, Oxidoreductases, Other, Unknown_function, SCAR, AuxillaryTransportUnit, StructuralAndAdhesion, Other_transporters, IG, Other_receptors, Transferases, Ligand, Isomerases, and Multiple functions.

Binding site distribution

Code
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import ast
pd.options.mode.chained_assignment = None

df_total_flat = pd.read_csv('./www/database/df_flattened.csv')
df_total_no_TM = pd.read_csv('./www/database/results_no_TM.csv')

list_columns = ['binding_sites', 'area_a2', 'alpha_seeds', 'beta_seeds', 'hydrophobicity']
for col in list_columns:
    df_total_no_TM[col] = df_total_no_TM[col].apply(lambda x: ast.literal_eval(x) if pd.notnull(x) else [])

all_classes = df_total_no_TM["main_class"].unique()
sub_classes = df_total_no_TM["sub_class_1"].unique()

avg_bs_dic = {}
protein_per_family_dic = {}
for item in sub_classes:
    all_no_sites = []
    protein_count = 0
    for index, row in df_total_no_TM.iterrows():
        if row["sub_class_1"] == item:
            all_no_sites.append(int(row["site"]))
            protein_count+=1
    if len(all_no_sites) == 0:
        print("error")
        continue
    else:
        avg_bs_dic[item] = sum(all_no_sites)/len(all_no_sites)
        protein_per_family_dic[item] = protein_count
        
subclass = [item for item in avg_bs_dic]
mainclass = []
for subs in subclass:
    if subs == "Unclassified":
        mainclass.append(list(set(list(df_total_no_TM[df_total_no_TM['sub_class_1'] == subs]["main_class"])))[0])
    else:
        mainclass.append(list(set(list(df_total_no_TM[df_total_no_TM['sub_class_1'] == subs]["main_class"])))[0])

Surfaceome = ["Surfaceome"] * 22
count = [protein_per_family_dic[c] for c in protein_per_family_dic]
bs = [avg_bs_dic[b] for b in avg_bs_dic]
df = pd.DataFrame(
    dict(subclass=subclass, mainclass=mainclass, Surfaceome=Surfaceome, count=count, BindingSites=bs)
)

fig = px.sunburst(df, 
                  path=['Surfaceome', 'mainclass', 'subclass'], 
                  width=800, height=800,
                  values='count',
                  color='BindingSites',
                  color_continuous_scale='RdBu',
                  color_continuous_midpoint=np.average(df['BindingSites'], weights=df['BindingSites']))

fig.update_traces(insidetextorientation="radial")
fig.update_layout(margin = dict(t=0, l=0, r=0, b=0))
# fig.update_traces(textfont=dict(family=['Arial'],size=[0,0,0,0,0]))
fig.show()

Binding site histogram on main classes

Code
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(6, 4))
sns.set_style("whitegrid")
g = sns.histplot(data=df_total_no_TM, x="site", hue="main_class", multiple="stack", discrete=True, kde=True, palette="dark")
g.set(xlim=(-0.5,9))
g.legend_.set_title(None)
plt.title("Binding site histogram per main class")
plt.show(g)

Seed distribution in sub-families

Code
avg_seed_a_dic = {}
avg_seed_b_dic = {}
for item in sub_classes:
    no_seeds_a = []
    no_seeds_b = []
    for i, row in df_total_no_TM.iterrows():
        if row["sub_class_1"] == item:
            no_seeds_a.append(sum(row["alpha_seeds"]))
            no_seeds_b.append(sum(row["beta_seeds"]))
    
    avg_seed_a_dic[item] = sum(no_seeds_a)/len(no_seeds_a)
    avg_seed_b_dic[item] = sum(no_seeds_b)/len(no_seeds_b)
    
count = [protein_per_family_dic[c] for c in protein_per_family_dic]
bs = [avg_bs_dic[b] for b in avg_bs_dic]
seed_a = [avg_seed_a_dic[a] for a in avg_seed_a_dic]
seed_b = [avg_seed_b_dic[b] for b in avg_seed_b_dic]

df2 = pd.DataFrame(
    dict(subclass=subclass, mainclass=mainclass, Surfaceome=Surfaceome, count=count, seed_a=seed_a, seed_b=seed_b)
)

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(style="whitegrid")

f, ax = plt.subplots(figsize=(5, 8))

sns.set_color_codes("colorblind")
sns.barplot(x="seed_b", y="subclass", data=df2,
            label="Beta seeds", color="b")

sns.set_color_codes("muted")
sns.barplot(x="seed_a", y="subclass", data=df2,
            label="Alpha seeds", color="r")

ax.legend(ncol=1, loc="lower right", frameon=True)
ax.set(xlim=(0, 5000), ylabel="",
       xlabel="Average seed distribution per sub-families")
ax.bar_label(ax.containers[0], fontsize=10);

sns.despine(left=True, bottom=True)

Correlation between Area and Hydrophobicity of the binding sites for Sub-familes

Code
order = ['Multiple functions', 'Transferases', 'Hydrolases', 'Isomerases', 'Lyases', 'Oxidoreductases',
        'Ligand', 'StructuralAndAdhesion', 'Multiple functions', 'Unknown_function',
        'SCAR', 'IG', 'Other_receptors', 'GPCR', 'Kinase',
        'Active_transporters', 'AuxillaryTransportUnit', 'Other_transporters', 'Channels', 'SLC',
        'Unclassified', 'Unmatched']
sns.set_style("whitegrid")
ax = sns.lmplot(
    data=df_total_flat, x="areass", y="hpss",
    hue="sub_classs", col="sub_classs", height=3, col_wrap=3, col_order=order, palette="muted"
)
ax.set(xlabel ="Area", ylabel = "Hydrophobicity")

Residue frequency in binding sites

Code
amino_acids = ['ALA', 'ARG', 'ASN', 'ASP', 'CYS', 'GLN', 'GLU', 'GLY', 'HIS', 'ILE', 
               'LEU', 'LYS', 'MET', 'PHE', 'PRO', 'SER', 'THR', 'TRP', 'TYR', 'VAL']

ordered_amino_acids = [
    'G', 'A', 'V', 'L', 'I', 'M', 'P',  # Nonpolar, aliphatic
    'F', 'Y', 'W',                      # Aromatic
    'S', 'T', 'C', 'N', 'Q',            # Polar, uncharged
    'K', 'R', 'H',                      # Positively charged
    'D', 'E'                            # Negatively charged
]

# Map full names to single letter codes for amino acids
amino_acid_map = {
    'ALA': 'A', 'ARG': 'R', 'ASN': 'N', 'ASP': 'D', 'CYS': 'C',
    'GLN': 'Q', 'GLU': 'E', 'GLY': 'G', 'HIS': 'H', 'ILE': 'I',
    'LEU': 'L', 'LYS': 'K', 'MET': 'M', 'PHE': 'F', 'PRO': 'P',
    'SER': 'S', 'THR': 'T', 'TRP': 'W', 'TYR': 'Y', 'VAL': 'V'
}

import re
from collections import Counter
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
list_accs = list(df_total_no_TM["acc"])

pattern = r'[0-9]'
list_AA_freq_dict = [] # a list of dictionaries containing all aa frequencies.
for i, ids in enumerate(list_accs):
    a = list(df_total_no_TM[df_total_no_TM['acc'] == ids]['residues'])[0]
    if a == []:
        list_AA_freq_dict.append({})
    else:
        a2 = re.sub(pattern, '', a)
        b = a2.replace("'","").replace("]},","").replace("]}]","").replace("]}","").replace("{cluster_: ","").replace("[_","").replace(" _","")
        b2 = b.replace("[ ","").split(",")

        freq_counter = Counter(b2)
        freq_dict = {amino_acid_map[aa]: freq_counter.get(aa, 0) for aa in amino_acids}
        list_AA_freq_dict.append(freq_dict)


df_total_no_TM['residues_unique'] = list_AA_freq_dict

freq_df = pd.DataFrame(df_total_no_TM['residues_unique'].tolist(), index=df_total_no_TM['acc'])
freq_df['main_class'] = df_total_no_TM['main_class'].tolist()
freq_df['sub_class'] = df_total_no_TM['sub_class_1'].tolist()
grouped_freq_df = freq_df.groupby('main_class').sum()
grouped_freq_df = grouped_freq_df[ordered_amino_acids]
grouped_freq_subclass_df = freq_df.groupby('sub_class').sum()
grouped_freq_subclass_df = grouped_freq_subclass_df[ordered_amino_acids]

epsilon = 1e-10
grouped_freq_df_norm = grouped_freq_df.div(grouped_freq_df.sum(axis=1) + epsilon, axis=0)
grouped_freq_subclass_df_norm = grouped_freq_subclass_df.div(grouped_freq_subclass_df.sum(axis=1) + epsilon, axis=0)

plt.figure(figsize=(12, 8))
sns.heatmap(grouped_freq_subclass_df_norm.T, cmap="jet", cbar_kws={'label': 'Frequency'}, square=True)
plt.title('Amino acid frequencies per protein sub-family',fontsize=15)
plt.xlabel('Protein sub-families',fontsize=15)
plt.ylabel('Amino acid',fontsize=15)
plt.show()