[2]:
import os,sys %matplotlib inline import numpy as np import matplotlib.pylab as plt import pickle plt.rcParams['figure.dpi'] = 100 plt.rcParams['savefig.dpi']=300 plt.rcParams['font.family']='sans serif' plt.rcParams['font.sans-serif']='Arial' plt.rcParams['pdf.fonttype']=42 sys.path.append(os.path.expanduser("~/Projects/Github/PyComplexHeatmap/")) import PyComplexHeatmap from PyComplexHeatmap import * use_pch_style() # or plt.style.use('default') to restore default style
Load an example brain networks dataset from seaborn¶
[3]:
import seaborn as sns # Load the brain networks dataset, select subset, and collapse the multi-index df = sns.load_dataset("brain_networks", header=[0, 1, 2], index_col=0) used_networks = [1, 5, 6, 7, 8, 12, 13, 17] used_columns = (df.columns .get_level_values("network") .astype(int) .isin(used_networks)) df = df.loc[:, used_columns] df.columns = df.columns.map("-".join) # Compute a correlation matrix and convert to long-form corr_mat = df.corr().stack().reset_index(name="correlation") corr_mat['Level']=corr_mat.correlation.apply(lambda x:'High' if x>=0.7 else 'Middle' if x >= 0.3 else 'Low') data=corr_mat.pivot(index='level_0',columns='level_1',values='correlation')
[4]:
data.head()
[4]:
level_1 | 1-1-lh | 1-1-rh | 12-1-lh | 12-1-rh | 12-2-lh | 12-2-rh | 12-3-lh | 13-1-lh | 13-1-rh | 13-2-lh | ... | 7-2-lh | 7-2-rh | 7-3-lh | 7-3-rh | 8-1-lh | 8-1-rh | 8-2-lh | 8-2-rh | 8-3-lh | 8-3-rh |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
level_0 | |||||||||||||||||||||
1-1-lh | 1.000000 | 0.881516 | -0.049793 | 0.026902 | -0.144335 | -0.141253 | 0.119250 | -0.261589 | -0.272701 | -0.370021 | ... | -0.366065 | -0.325680 | -0.196770 | -0.144566 | -0.366818 | -0.388756 | -0.352529 | -0.363982 | -0.341524 | -0.350452 |
1-1-rh | 0.881516 | 1.000000 | -0.112697 | -0.036909 | -0.144277 | -0.189683 | 0.084633 | -0.324230 | -0.332886 | -0.374322 | ... | -0.361036 | -0.274151 | -0.142392 | -0.070452 | -0.358625 | -0.402173 | -0.302286 | -0.339989 | -0.315931 | -0.343379 |
12-1-lh | -0.049793 | -0.112697 | 1.000000 | 0.343464 | 0.470239 | 0.100802 | 0.438449 | 0.339667 | 0.089811 | 0.272394 | ... | -0.036493 | -0.171179 | -0.043298 | -0.158039 | 0.005598 | -0.060007 | 0.079078 | -0.040060 | 0.027878 | -0.075781 |
12-1-rh | 0.026902 | -0.036909 | 0.343464 | 1.000000 | 0.130549 | 0.278569 | 0.127621 | -0.014404 | 0.051249 | -0.090130 | ... | -0.170053 | -0.124278 | -0.112148 | -0.063705 | -0.172007 | -0.040629 | -0.079687 | 0.024864 | -0.092263 | -0.068858 |
12-2-lh | -0.144335 | -0.144277 | 0.470239 | 0.130549 | 1.000000 | 0.521377 | 0.506652 | 0.320966 | 0.141884 | 0.608392 | ... | -0.075986 | -0.095015 | 0.012966 | -0.082816 | 0.023340 | 0.058718 | 0.034181 | 0.033355 | -0.022982 | 0.025638 |
5 rows × 38 columns
[5]:
corr_mat.Level.value_counts().index.tolist()
[5]:
['Low', 'Middle', 'High']
[6]:
corr_mat.head()
[6]:
level_0 | level_1 | correlation | Level | |
---|---|---|---|---|
0 | 1-1-lh | 1-1-lh | 1.000000 | High |
1 | 1-1-lh | 1-1-rh | 0.881516 | High |
2 | 1-1-lh | 5-1-lh | 0.431619 | Middle |
3 | 1-1-lh | 5-1-rh | 0.418708 | Middle |
4 | 1-1-lh | 6-1-lh | -0.084634 | Low |
Dot Heatmap¶
Plot traditional heatmap using square marker marker='s'
¶
[7]:
plt.figure(figsize=(8,8)) cm = DotClustermapPlotter(data=corr_mat,x='level_0',y='level_1',value='correlation', c='correlation',cmap='jet',vmax=1,vmin=0,s=0.7,marker='s',spines=True) cm.ax_heatmap.grid(which='minor',color='white',linestyle='--',linewidth=1) plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 132.808800071564 Collecting legends.. Plotting legends.. Estimated legend width: 7.5 mm

Simple dot heatmap using fixed dot size¶
In default, using circle marker: marker='o'
[9]:
plt.figure(figsize=(8,8)) cm = DotClustermapPlotter(corr_mat,x='level_0',y='level_1',value='correlation', c='correlation',s=0.5,cmap='Oranges',vmax=1,vmin=0) plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 132.808800071564 Collecting legends.. Plotting legends.. Estimated legend width: 7.5 mm

Changing the size of point¶
In default, we determined the size of the points based on the value
col if parameter s
was not given
[20]:
plt.figure(figsize=(8,8)) cm = DotClustermapPlotter(corr_mat,x='level_0',y='level_1',value='correlation', s='correlation',cmap='RedYellowBlue_r',c='correlation', vmax=1,vmin=0, linewidth=0.5,edgecolor='black') plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 132.808800071564 Collecting legends.. Plotting legends.. Estimated legend width: 28.22361111111111 mm

Add parameter hue
and use different colors
for different groups¶
[16]:
plt.figure(figsize=(8,8)) cm = DotClustermapPlotter( corr_mat,x='level_0',y='level_1',value='correlation',hue='Level', colors={'High':'red','Middle':'purple','Low':'green'}, s='correlation',vmax=1,vmin=0) plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 132.808800071564 Collecting legends.. Plotting legends.. Estimated legend width: 28.22361111111111 mm

Add parameter hue
and use different cmap
and marker
for different groups¶
[17]:
plt.figure(figsize=(8,8)) cm = DotClustermapPlotter(corr_mat,x='level_0',y='level_1',value='correlation',hue='Level', colors={'High':'red','Middle':'purple','Low':'green'}, #in this case, colors is only used to control the color in the legend marker={'High':'P','Middle':'*','Low':'D'}, spines=True, vmax=1,vmin=0,legend_width=18) plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 132.808800071564 Collecting legends.. Plotting legends..

[18]:
plt.figure(figsize=(8,8)) cm = DotClustermapPlotter(corr_mat,x='level_0',y='level_1',value='correlation',hue='Level', cmap={'High':'Reds','Middle':'Purples','Low':'Greens'}, colors={'High':'red','Middle':'purple','Low':'green'}, #in this case, colors is only used to control the color in the legend marker={'High':'P','Middle':'*','Low':'D'}, spines=True, vmax=1,vmin=0,legend_width=18) plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 132.808800071564 Collecting legends.. Plotting legends..

Dot Clustermap¶
Plot clustermap using seaborn brain networks dataset¶
[19]:
corr_mat.head()
[19]:
level_0 | level_1 | correlation | Level | |
---|---|---|---|---|
0 | 1-1-lh | 1-1-lh | 1.000000 | High |
1 | 1-1-lh | 1-1-rh | 0.881516 | High |
2 | 1-1-lh | 5-1-lh | 0.431619 | Middle |
3 | 1-1-lh | 5-1-rh | 0.418708 | Middle |
4 | 1-1-lh | 6-1-lh | -0.084634 | Low |
[20]:
df_row=corr_mat['level_0'].drop_duplicates().to_frame() df_row['RowGroup']=df_row.level_0.apply(lambda x:x.split('-')[0]) df_row.set_index('level_0',inplace=True) df_col=corr_mat['level_1'].drop_duplicates().to_frame() df_col['ColGroup']=df_col.level_1.apply(lambda x:x.split('-')[0]) df_col.set_index('level_1',inplace=True) print(df_row.head()) print(df_col.head())
RowGroup level_0 1-1-lh 1 1-1-rh 1 5-1-lh 5 5-1-rh 5 6-1-lh 6 ColGroup level_1 1-1-lh 1 1-1-rh 1 5-1-lh 5 5-1-rh 5 6-1-lh 6
[21]:
row_ha = HeatmapAnnotation(Row=anno_simple(df_row.RowGroup,cmap='Set1', add_text=True,text_kws={'color':'black','rotation':-90}, legend=False), axis=0,verbose=0,label_kws={'rotation':45,'horizontalalignment':'left'}) col_ha = HeatmapAnnotation(label=anno_label(df_col.ColGroup, merge=True,rotation=45), Col=anno_simple(df_col.ColGroup,cmap='Dark2',legend=False,add_text=True), verbose=0,label_side='left',label_kws={'horizontalalignment':'right'}) plt.figure(figsize=(9, 8)) cm = DotClustermapPlotter(data=corr_mat, x='level_0',y='level_1',value='correlation', hue='Level', cmap={'High':'Reds','Middle':'Purples','Low':'Greens'}, colors={'High':'red','Middle':'purple','Low':'green'}, marker={'High':'P','Middle':'*','Low':'D'}, top_annotation=col_ha,right_annotation=row_ha, col_split=2,row_split=2, col_split_gap=0.5,row_split_gap=1, show_rownames=True,show_colnames=True,row_dendrogram=True, tree_kws={'row_cmap': 'Set1'},verbose=0,legend_gap=7,spines=True,) plt.show()

Visualize up to five dimension data using DotClustermapPlotter¶
Plot enrichment analysis result using example dataset with samples annotations
[22]:
data=pd.read_csv("../data/kycg_result.txt",sep='\t') data=data.loc[data.Category.isin(['rmsk1','ChromHMM','EnsRegBuild'])] data.SampleID.replace({'Clark2018_Argelaguet2019':'Dataset1','Luo2022':'Dataset2'},inplace=True) max_p=np.nanmax(data['-log10(Pval)'].values) data['-log10(Pval)'].fillna(max_p,inplace=True) data['ID']=data.SampleID + '-' + data.CpGType vc=data.groupby('Term').SampleID.apply(lambda x:x.nunique()) data=data.loc[data.Term.isin(vc[vc>=2].index.tolist())] # p_max=data['-log10(Pval)'].max() # p_min=data['-log10(Pval)'].min() # data['-log10(Pval)']=data['-log10(Pval)'].apply(lambda x:(x-p_min)/(p_max-p_min)) df_col=data.ID.drop_duplicates().to_frame() df_col['Dataset']=df_col.ID.apply(lambda x:x.split('-')[0]) df_col['Correlation']=df_col.ID.apply(lambda x:x.split('-')[1]) df_col.set_index('ID',inplace=True) df_row=data.loc[:,['Term','Category']].drop_duplicates() df_row.set_index('Term',inplace=True)
[23]:
data.head()
[23]:
Term | odds_ratio | Category | SampleID | CpGType | pvalue | EnrichType | -log10(Pval) | ID | |
---|---|---|---|---|---|---|---|---|---|
49 | Het | 1.061 | ChromHMM | Dataset1 | Negative | 2.020000e-07 | Enrich | 26.0 | Dataset1-Negative |
55 | Tx | 1.029 | ChromHMM | Dataset1 | Negative | 4.580000e-07 | Enrich | 26.0 | Dataset1-Negative |
65 | TssFlnk | 1.056 | ChromHMM | Dataset1 | Negative | 2.370000e-06 | Enrich | 26.0 | Dataset1-Negative |
112 | TxWk | 1.022 | ChromHMM | Dataset1 | Negative | 8.660000e-05 | Enrich | 26.0 | Dataset1-Negative |
346 | DNA? | 1.350 | rmsk1 | Dataset1 | Negative | 2.760000e-02 | Enrich | 26.0 | Dataset1-Negative |
[24]:
data['-log10(Pval)'].describe()
[24]:
count 64.000000 mean 25.356918 std 3.632073 min 3.119186 25% 26.000000 50% 26.000000 75% 26.000000 max 26.000000 Name: -log10(Pval), dtype: float64
[25]:
print(data.CpGType.unique()) print(data.EnrichType.unique())
['Negative' 'Positive'] ['Enrich' 'Depletion']
[26]:
df_col
[26]:
Dataset | Correlation | |
---|---|---|
ID | ||
Dataset1-Negative | Dataset1 | Negative |
Dataset1-Positive | Dataset1 | Positive |
Dataset2-Negative | Dataset2 | Negative |
Dataset2-Positive | Dataset2 | Positive |
[27]:
df_row
[27]:
Category | |
---|---|
Term | |
Het | ChromHMM |
Tx | ChromHMM |
TssFlnk | ChromHMM |
TxWk | ChromHMM |
DNA? | rmsk1 |
srpRNA | rmsk1 |
DNA | rmsk1 |
Unknown | rmsk1 |
Satellite | rmsk1 |
Simple_repeat | rmsk1 |
Low_complexity | rmsk1 |
LINE | rmsk1 |
Quies | ChromHMM |
ReprPCWk | ChromHMM |
TssBiv | ChromHMM |
ReprPC | ChromHMM |
LTR | rmsk1 |
snRNA | rmsk1 |
SINE | rmsk1 |
[28]:
row_ha = HeatmapAnnotation( Category=anno_simple(df_row.Category,cmap='Set1', add_text=False,legend=False), label=anno_label(df_row.Category, merge=True,rotation=0), axis=0,verbose=0,label_kws={'rotation':45,'horizontalalignment':'left'}) col_ha = HeatmapAnnotation( Dataset=anno_simple(df_col.Dataset,cmap='Set1',legend=False,add_text=True), Correlation=anno_simple(df_col.Correlation,cmap='Dark2',legend=False,add_text=True), verbose=0,label_side='left',label_kws={'horizontalalignment':'right'}) plt.figure(figsize=(3, 5)) cm = DotClustermapPlotter(data=data, x='ID',y='Term',value='-log10(Pval)',c='-log10(Pval)',s='odds_ratio', hue='EnrichType', row_cluster=False,col_cluster=False, cmap={'Enrich':'RdYlGn_r','Depletion':'coolwarm_r'}, colors={'Enrich':'red','Depletion':'blue'}, #marker={'Enrich':'^','Depletion':'v'}, top_annotation=col_ha,right_annotation=row_ha, col_split=df_col.Dataset,row_split=df_row.Category, col_split_gap=0.5,row_split_gap=1, show_rownames=True,show_colnames=False,row_dendrogram=False, verbose=1,legend_gap=7) #if the size of dot in legend is too large, use alpha to control, for example: alpha=0.8 plt.savefig("dotHeatmap1.pdf",bbox_inches='tight') plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 180.09263168093761 Collecting legends.. Plotting legends.. Estimated legend width: 25.930555555555557 mm

[29]:
plt.figure(figsize=(3.5, 5)) cm = DotClustermapPlotter(data=data, x='ID',y='Term',value='odds_ratio',s='-log10(Pval)', hue='EnrichType', row_cluster=False,#cmap='jet', colors={'Enrich':'red','Depletion':'blue'},c='-log10(Pval)', cmap={'Enrich':'Reds','Depletion':'Blues'}, marker={'Enrich':'$\\ast$','Depletion':'X'},value_na=25,c_na=25, top_annotation=col_ha,right_annotation=row_ha, col_split=df_col.Dataset,row_split=df_row.Category, col_split_gap=0.5,row_split_gap=1, show_rownames=True,verbose=1,legend_gap=7,dot_legend_marker='o') # plt.savefig(os.path.expanduser("~/Gallery/20230227_kycg.pdf"),bbox_inches='tight') plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 180.09263168093761 Collecting legends.. Plotting legends.. Estimated legend width: 30.516666666666666 mm

[30]:
data['-log10(Pval)'].describe()
[30]:
count 64.000000 mean 25.356918 std 3.632073 min 3.119186 25% 26.000000 50% 26.000000 75% 26.000000 max 26.000000 Name: -log10(Pval), dtype: float64
[31]:
plt.figure(figsize=(3.5, 4)) cm = DotClustermapPlotter(data=data, x='ID',y='Term',value='-log10(Pval)',c='-log10(Pval)',s='odds_ratio', hue='EnrichType', row_cluster=False,col_cluster=False,cmap='jet', colors={'Enrich':'red','Depletion':'blue'}, # marker={'Enrich':'P','Depletion':'*'}, value_na=25,c_na=25, top_annotation=col_ha,right_annotation=row_ha, col_split=df_col.Dataset,row_split=df_row.Category, col_split_gap=0.5,row_split_gap=1, show_rownames=True,verbose=1,legend_gap=7,spines=True,dot_legend_marker='D') plt.show()
Starting plotting.. Starting calculating row orders.. Reordering rows.. Starting calculating col orders.. Reordering cols.. Plotting matrix.. Inferred max_s (max size of scatter point) is: 110.41377726332676 Collecting legends.. Plotting legends.. Estimated legend width: 25.930555555555557 mm

[ ]: