[5]:
import os,sys
%matplotlib inline
import matplotlib.pylab as plt
import pickle
import numpy as np
plt.rcParams['figure.dpi'] = 100
plt.rcParams['savefig.dpi']=300
sys.path.append(os.path.expanduser("~/Projects/Github/PyComplexHeatmap"))
import PyComplexHeatmap
print(PyComplexHeatmap.__version__)
from PyComplexHeatmap import *
1.7.7.dev0+gddb18da.d20240909
[6]:
#set font to Arial using the following code
plt.rcParams['font.family']='sans serif'
plt.rcParams['font.sans-serif']='Arial'
# set pdf.fonttype to 42
plt.rcParams['pdf.fonttype']=42

Understand the layout:

[3]:
#Generate example dataset (random)
df = pd.DataFrame(['GroupA'] * 5 + ['GroupB'] * 5, columns=['AB'])
df['CD'] = ['C'] * 3 + ['D'] * 3 + ['G'] * 4
df['EF'] = ['E'] * 6 + ['F'] * 2 + ['H'] * 2
df['F'] = np.random.normal(0, 1, 10)
df.index = ['sample' + str(i) for i in range(1, df.shape[0] + 1)]
df_box = pd.DataFrame(np.random.randn(10, 4), columns=['Gene' + str(i) for i in range(1, 5)])
df_box.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar = pd.DataFrame(np.random.uniform(0, 10, (10, 2)), columns=['TMB1', 'TMB2'])
df_bar.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_scatter = pd.DataFrame(np.random.uniform(0, 10, 10), columns=['Scatter'])
df_scatter.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_heatmap = pd.DataFrame(np.random.randn(30, 10), columns=['sample' + str(i) for i in range(1, 11)])
df_heatmap.index = ["Fea" + str(i) for i in range(1, df_heatmap.shape[0] + 1)]
df_heatmap.iloc[1, 2] = np.nan
[4]:
#Annotate the rows with average > 0.3
df_rows = df_heatmap.apply(lambda x:x.name if x.sample4 > 0.5 else None,axis=1)
df_rows=df_rows.to_frame(name='Selected')
df_rows['XY']=df_rows.index.to_series().apply(lambda x:'A' if int(x.replace('Fea',''))>=15 else 'B')

row_ha = HeatmapAnnotation(
            S4=anno_simple(df_heatmap.sample4.apply(lambda x:round(x,2)),
                       height=10,#add_text=True,
                       text_kws={'rotation':0,'fontsize':10,'color':'black'}),
            Test=anno_barplot(df_heatmap.sample4.apply(lambda x:round(x,2)),
                        height=18,cmap='rainbow'),
            selected=anno_label(df_rows,colors='red',relpos=(0,0.5)),
            axis=0,verbose=0,wgap=4,label_kws={'rotation':0,'horizontalalignment':'left',
                                        'verticalalignment':'bottom'})

col_ha = HeatmapAnnotation(
            label=anno_label(df.AB, merge=True,rotation=15),
            AB=anno_simple(df.AB,add_text=True,height=5),axis=1,
            CD=anno_simple(df.CD,add_text=True,height=5),
            EF=anno_simple(df.EF,add_text=True,height=5,
                            legend_kws={'frameon':False}),
            Exp=anno_boxplot(df_box, cmap='turbo',grid=True),
            verbose=0,hgap=2) #verbose=0 will turn off the log.

plt.figure(figsize=(6, 8))
cm = ClusterMapPlotter(
            data=df_heatmap, top_annotation=col_ha,right_annotation=row_ha,
            col_split=df.AB,
            row_split=df_rows.XY,
            col_split_gap=3.5,row_split_gap=2.5,
            col_cluster=True,row_cluster=True,
            label='values',row_dendrogram=False,
            show_rownames=True,show_colnames=True,
            verbose=0,legend_gap=5,legend_hpad=10,legend_vpad=5,
            #annot=True,fmt='.1g',linewidths=0.05,linecolor='gold',
            cmap='RdYlBu_r',
            xticklabels_kws={'labelrotation':-45,'labelcolor':'blue'},
            yticklabels_kws=dict(labelcolor='red',pad=20),
            subplot_gap=8,
            xlabel='Samples',xlabel_kws=dict(color='white',fontsize=14,labelpad=25,position=(0,0)),
            xlabel_bbox_kws=dict(facecolor='black'),ylabel_bbox_kws=dict(facecolor='green'),
            ylabel='Features',ylabel_kws=dict(color='black',fontsize=14,labelpad=45,position=(0,0)),
)
for ax,color in zip([cm.ax,cm.ax_heatmap,cm.ax_top,cm.ax_right],['red','purple','blue','chocolate']):
    for side in ["top", "right", "left", "bottom"]:
        ax.set_axis_on()
        # ax.yaxis.set_visible(True)
        # ax.xaxis.set_visible(True)
        ax.spines[side].set_visible(True)
        ax.spines[side].set_color(color)
        ax.spines[side].set_linewidth(2)
        ax.spines[side].set_linestyle('--')
plt.show()
../_images/notebooks_dev_4_0.png
[5]:
cm.ax.xaxis.label.properties()
[5]:
{'agg_filter': None,
 'alpha': None,
 'animated': False,
 'bbox_patch': <matplotlib.patches.FancyBboxPatch at 0x7fb4d5a69fa0>,
 'children': [],
 'clip_box': None,
 'clip_on': True,
 'clip_path': None,
 'color': 'white',
 'figure': <Figure size 600x800 with 31 Axes>,
 'fontfamily': ['sans serif'],
 'fontname': 'Arial',
 'fontproperties': <matplotlib.font_manager.FontProperties at 0x7fb4d59faee0>,
 'fontsize': 14.0,
 'fontstyle': 'normal',
 'fontvariant': 'normal',
 'fontweight': 'normal',
 'gid': None,
 'horizontalalignment': 'center',
 'in_layout': True,
 'label': '',
 'math_fontfamily': 'dejavusans',
 'mouseover': False,
 'parse_math': True,
 'path_effects': [],
 'picker': None,
 'position': (0, 23.000000000000007),
 'rasterized': False,
 'rotation': 0.0,
 'rotation_mode': None,
 'sketch_params': None,
 'snap': None,
 'stretch': 'normal',
 'text': 'Samples',
 'tightbbox': Bbox([[37.125, 5.000000000000007], [112.875, 23.000000000000007]]),
 'transform': <matplotlib.transforms.BlendedAffine2D at 0x7fb4d59faf70>,
 'transform_rotates_text': False,
 'transformed_clip_path_and_affine': (None, None),
 'unitless_position': (0.0, 23.000000000000007),
 'url': None,
 'usetex': False,
 'verticalalignment': 'top',
 'visible': True,
 'window_extent': Bbox([[37.125, 5.000000000000007], [112.875, 23.000000000000007]]),
 'wrap': False,
 'zorder': 3}
[6]:
cm.ax.xaxis.label.get_bbox_patch().properties()
[6]:
{'agg_filter': None,
 'alpha': None,
 'animated': False,
 'antialiased': True,
 'bbox': Bbox([[0.0, 0.0], [75.75, 18.0]]),
 'boxstyle': <matplotlib.patches.BoxStyle.Square at 0x7fb4d5f01b20>,
 'capstyle': 'butt',
 'children': [],
 'clip_box': None,
 'clip_on': True,
 'clip_path': None,
 'data_transform': <matplotlib.transforms.Affine2D at 0x7fb4d69d2430>,
 'edgecolor': (0.0, 0.0, 0.0, 1.0),
 'extents': Bbox([[47.54166666666667, -0.6388888888888813], [134.56944444444446, 28.638888888888896]]),
 'facecolor': (0.0, 0.0, 0.0, 1.0),
 'figure': None,
 'fill': True,
 'gid': None,
 'hatch': None,
 'height': 18.0,
 'in_layout': True,
 'joinstyle': 'miter',
 'label': '',
 'linestyle': 'solid',
 'linewidth': 1.0,
 'mouseover': False,
 'mutation_aspect': 1,
 'mutation_scale': 19.444444444444443,
 'patch_transform': <matplotlib.transforms.IdentityTransform at 0x7fb4d59874c0>,
 'path': Path(array([[-5.63888889, -5.63888889],
        [81.38888889, -5.63888889],
        [81.38888889, 23.63888889],
        [-5.63888889, 23.63888889],
        [-5.63888889, -5.63888889]]), array([ 1,  2,  2,  2, 79], dtype=uint8)),
 'path_effects': [],
 'picker': None,
 'rasterized': False,
 'sketch_params': None,
 'snap': None,
 'tightbbox': Bbox([[47.54166666666667, -0.6388888888888813], [134.56944444444446, 28.638888888888896]]),
 'transform': <matplotlib.transforms.Affine2D at 0x7fb4d69d2430>,
 'transformed_clip_path_and_affine': (None, None),
 'url': None,
 'verts': array([[ 47.54166667,  -0.63888889],
        [134.56944444,  -0.63888889],
        [134.56944444,  28.63888889],
        [ 47.54166667,  28.63888889],
        [ 47.54166667,  -0.63888889]]),
 'visible': True,
 'width': 75.75,
 'window_extent': Bbox([[47.54166666666667, -0.6388888888888813], [134.56944444444446, 28.638888888888896]]),
 'x': 0.0,
 'y': 0.0,
 'zorder': 1}

Bezier dendrogram

[3]:
df = pd.DataFrame(['GroupA'] * 5 + ['GroupB'] * 5, columns=['AB'])
df['CD'] = ['C'] * 3 + ['D'] * 3 + ['G'] * 4
df['EF'] = ['E'] * 6 + ['F'] * 2 + ['H'] * 2
df['F'] = np.random.normal(0, 1, 10)
df.index = ['sample' + str(i) for i in range(1, df.shape[0] + 1)]

df_heatmap = pd.DataFrame(np.random.randn(30, 10), columns=['sample' + str(i) for i in range(1, 11)])
df_heatmap.index = ["Fea" + str(i) for i in range(1, df_heatmap.shape[0] + 1)]
df_heatmap.iloc[1, 2] = np.nan

plt.figure(figsize=(3.5, 5))
cm = ClusterMapPlotter(
        data=df_heatmap.fillna(0),
        col_cluster=True,row_cluster=True,
        # col_split=df.AB,
        row_split=2,
        col_split_gap=0.5,row_split_gap=0.8,
        label='values',row_dendrogram=True,col_dendrogram=True,
        show_rownames=True,show_colnames=True,bezier=True,dotsize=3,
        row_names_side='right',yticklabels=True,
        tree_kws=dict(colors='blue'),verbose=0,legend_gap=5,
        cmap='meth2',xticklabels_kws={'labelrotation':-90,'labelcolor':'blue'})
plt.show()
../_images/notebooks_dev_8_0.png
[4]:
dendrogram_row = PyComplexHeatmap.DendrogramPlotter(
                    df_heatmap.fillna(0),
                    linkage=None,
                    axis=0,
                    label=True,
                    rotate=True,
            )
[5]:
plt.figure(figsize=(6,8))
ax=plt.gca()
dendrogram_row.plot(ax=ax,bezier=True,dotsize=8,tree_kws=dict(colors='red'))
plt.savefig("test.pdf",bbox_inches='tight')
plt.show()
../_images/notebooks_dev_10_0.png
[6]:
#Generate example dataset (random)
df = pd.DataFrame(['GroupA'] * 5 + ['GroupB'] * 5, columns=['AB'])
df['CD'] = ['C'] * 3 + ['D'] * 3 + ['G'] * 4
df['EF'] = ['E'] * 6 + ['F'] * 2 + ['H'] * 2
df['F'] = np.random.normal(0, 1, 10)
df.index = ['sample' + str(i) for i in range(1, df.shape[0] + 1)]
df_box = pd.DataFrame(np.random.randn(10, 4), columns=['Gene' + str(i) for i in range(1, 5)])
df_box.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar = pd.DataFrame(np.random.uniform(0, 10, (10, 2)), columns=['TMB1', 'TMB2'])
df_bar.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_scatter = pd.DataFrame(np.random.uniform(0, 10, 10), columns=['Scatter'])
df_scatter.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_heatmap = pd.DataFrame(np.random.randn(30, 10), columns=['sample' + str(i) for i in range(1, 11)])
df_heatmap.index = ["Fea" + str(i) for i in range(1, df_heatmap.shape[0] + 1)]
df_heatmap.iloc[1, 2] = np.nan
# add a missing value to sample4
df_heatmap.loc['Fea4','sample4']=np.nan
df_box.loc['sample4','Gene4']=np.nan
df_box
[6]:
Gene1 Gene2 Gene3 Gene4
sample1 -0.205718 -0.946868 0.511483 0.893269
sample2 -0.077131 -0.299588 0.096398 -0.268682
sample3 0.039453 -1.376546 0.018616 0.393587
sample4 -0.066739 -0.168233 1.930738 NaN
sample5 0.980476 1.017062 -1.141064 1.709422
sample6 0.189646 0.815627 -0.542022 -0.414366
sample7 1.318299 -0.144643 0.068143 1.429474
sample8 3.010217 -2.927032 1.681276 0.475914
sample9 -0.066108 -0.873660 -0.553423 0.567739
sample10 0.179432 -0.391544 0.152426 1.488862
[7]:
df['Groups']=['G1']+['G2']+['G3']*5+['G4']+['G5']*2
col_ha = HeatmapAnnotation(
            Groups=anno_simple(df.Groups,add_text=True,text_kws={'color':'black'}),
            AB=anno_simple(df.AB,add_text=True),axis=1,
            Exp=anno_boxplot(df_box, cmap='turbo'),
            verbose=0) #verbose=0 will turn off the log.
plt.figure(figsize=(8, 10))
cm = ClusterMapPlotter(
        data=df_heatmap, top_annotation=col_ha,
        col_split=df.Groups, col_split_order="cluster_between_groups",
        col_split_gap=2,col_cluster=False,
        row_cluster=True,col_dendrogram=True,row_dendrogram_size=35,col_dendrogram_size=25,
        row_split=2,row_split_gap=1,row_dendrogram=True,
        label='values',show_rownames=True,show_colnames=True,bezier=True,dotsize=8,
        tree_kws={'colors':'blue','row_cmap':'Set1','col_cmap':'Paired'},
        verbose=0,legend_gap=7,
        linewidths=0.05,linecolor='gold',cmap='RdYlBu_r',
        xticklabels_kws={'labelrotation':-45,'labelcolor':'blue'},
        ylabel='Features')
plt.savefig("test2.pdf") #bbox_inches='tight'
plt.show()
../_images/notebooks_dev_12_0.png

anno_label

[12]:
#Generate example dataset (random)
df = pd.DataFrame(['GroupA'] * 5 + ['GroupB'] * 5, columns=['AB'])
df['CD'] = ['C'] * 3 + ['D'] * 3 + ['G'] * 4
df['EF'] = ['E'] * 6 + ['F'] * 2 + ['H'] * 2
df['F'] = np.random.normal(0, 1, 10)
df.index = ['sample' + str(i) for i in range(1, df.shape[0] + 1)]
df_box = pd.DataFrame(np.random.randn(10, 4), columns=['Gene' + str(i) for i in range(1, 5)])
df_box.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar = pd.DataFrame(np.random.uniform(0, 10, (10, 2)), columns=['TMB1', 'TMB2'])
df_bar.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_scatter = pd.DataFrame(np.random.uniform(0, 10, 10), columns=['Scatter'])
df_scatter.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_heatmap = pd.DataFrame(np.random.randn(30, 10), columns=['sample' + str(i) for i in range(1, 11)])
df_heatmap.index = ["Fea" + str(i) for i in range(1, df_heatmap.shape[0] + 1)]
df_heatmap.iloc[1, 2] = np.nan
[13]:
#Annotate the rows with average > 0.3
df_rows = df_heatmap.apply(lambda x:x.name if x.sample4 > 0.5 else None,axis=1)
df_rows=df_rows.to_frame(name='Selected')
df_rows['XY']=df_rows.index.to_series().apply(lambda x:'A' if int(x.replace('Fea',''))>=15 else 'B')

row_ha = HeatmapAnnotation(
            S4=anno_simple(df_heatmap.sample4.apply(lambda x:round(x,2)),
                       add_text=True,height=10,
                       text_kws={'rotation':0,'fontsize':10,'color':'black'}),
            # Scatter=anno_scatterplot(df_heatmap.sample4.apply(lambda x:round(x,2)),
            #                  height=10),
            Test=anno_barplot(df_heatmap.sample4.apply(lambda x:round(x,2)),
                        height=18,cmap='rainbow'),
            selected=anno_label(df_rows,colors='red',height=20,extend=True),
            axis=0,verbose=0,#wgap=4,
            label_kws={'rotation':0,'horizontalalignment':'left',
                                        'verticalalignment':'bottom'})

plt.figure(figsize=(6, 8))
cm = ClusterMapPlotter(
            data=df_heatmap,right_annotation=row_ha,
            col_split=df.AB,
            # row_split=df_rows.XY,
            #col_split_gap=3.5,row_split_gap=2.5,
            col_cluster=True,row_cluster=True,
            label='values',row_dendrogram=False,
            show_rownames=True,show_colnames=True,
            verbose=0,legend_gap=5,#legend_hpad=10,legend_vpad=5,
            linewidths=0.05,linecolor='gold',cmap='RdYlBu_r',
            xticklabels_kws={'labelrotation':-45,'labelcolor':'blue'},
            yticklabels_kws=dict(labelcolor='red'),#subplot_gap=8
)
ax=cm.right_annotation.annotations[2].ax
for side in ["top", "right", "left", "bottom"]:
    ax.set_axis_on()
    ax.spines[side].set_visible(True)
    ax.spines[side].set_color('red')
    ax.spines[side].set_linewidth(2)
    ax.spines[side].set_linestyle('--')
ax.tick_params(axis="y", which="both", bottom=True, labelbottom=True,left=False,labelleft=False,right=True,labelright=True)
ax.yaxis.tick_right()
ax.yaxis.set_visible(True)
plt.show()
../_images/notebooks_dev_15_0.png
[14]:
row_ha = HeatmapAnnotation(
            selected=anno_label(df_rows,colors='red',height=20),
            Test=anno_barplot(df_heatmap.sample4.apply(lambda x:round(x,2) if x > 0 else None),
                        height=30,cmap='rainbow'),
            axis=0,verbose=0,#wgap=4,
            label_kws={'rotation':0,'horizontalalignment':'left',
                                        'verticalalignment':'bottom'})

plt.figure(figsize=(6, 8))
cm = ClusterMapPlotter(
            data=df_heatmap, left_annotation=row_ha,
            col_split=df.AB,
            row_split=df_rows.XY,
            #col_split_gap=3.5,row_split_gap=2.5,
            col_cluster=True,row_cluster=True,
            label='values',row_dendrogram=False,
            show_rownames=True,show_colnames=True,row_names_side='right',
            verbose=0,legend_gap=5,#legend_hpad=10,legend_vpad=5,
            linewidths=0.05,linecolor='gold',cmap='RdYlBu_r',
            xticklabels_kws={'labelrotation':-45,'labelcolor':'blue'},
            yticklabels_kws=dict(labelcolor='red'),#subplot_gap=8
)
for ax in cm.left_annotation.axes.flatten():
    for side in ["top", "right", "left", "bottom"]:
        ax.set_axis_on()
        ax.spines[side].set_visible(True)
        ax.spines[side].set_color('red')
        ax.spines[side].set_linewidth(1)
        ax.spines[side].set_linestyle('--')
plt.show()
../_images/notebooks_dev_16_0.png
[15]:
row_ha = HeatmapAnnotation(
            selected=anno_label(df_rows,colors='red',rotation=90),
            S4=anno_simple(df_heatmap.sample4.apply(lambda x:round(x,2)),
                       height=4),
            Test=anno_barplot(df_heatmap.sample4.apply(lambda x:round(x,2)),
                        height=8,cmap='rainbow'),
            axis=1,verbose=0,#wgap=4,
            label_kws={'rotation':0,'horizontalalignment':'left',
                                        'verticalalignment':'bottom'})

plt.figure(figsize=(8, 6))
cm = ClusterMapPlotter(
            data=df_heatmap.T, top_annotation=row_ha,
            row_split=df.AB,
            col_split=df_rows.XY,
            #col_split_gap=3.5,row_split_gap=2.5,
            col_cluster=True,row_cluster=True,
            label='values',row_dendrogram=False,
            show_rownames=True,show_colnames=True,row_names_side='right',
            verbose=0,legend_gap=5,#legend_hpad=10,legend_vpad=5,
            linewidths=0.05,linecolor='gold',cmap='RdYlBu_r',
            xticklabels_kws={'labelrotation':-45,'labelcolor':'blue'},
            yticklabels_kws=dict(labelcolor='red'),#subplot_gap=8
)
plt.show()
../_images/notebooks_dev_17_0.png
[16]:
col_ha = HeatmapAnnotation(
            S4=anno_simple(df_heatmap.sample4.apply(lambda x:round(x,2)),
                       height=4),
            Test=anno_barplot(df_heatmap.sample4.apply(lambda x:round(x,2)),
                        height=8,cmap='rainbow'),
            selected=anno_label(df_rows,colors='red',relpos=(0.7,1),height=15,extend=True),
            axis=1,verbose=0,#wgap=4,
            label_kws={'rotation':0,'horizontalalignment':'left',
                                        'verticalalignment':'bottom'})

plt.figure(figsize=(8, 6))
cm = ClusterMapPlotter(
            data=df_heatmap.T, bottom_annotation=col_ha,
            row_split=df.AB,
            col_split=df_rows.XY,
            col_split_gap=3.5,row_split_gap=2.5,
            col_cluster=True,row_cluster=True,
            label='values',row_dendrogram=False,
            show_rownames=True,show_colnames=True,row_names_side='right',
            verbose=0,legend_gap=5,#legend_hpad=10,legend_vpad=5,
            linewidths=0.05,linecolor='gold',cmap='RdYlBu_r',
            xticklabels_kws={'labelrotation':45,'labelcolor':'blue'},
            yticklabels_kws=dict(labelcolor='red'),#subplot_gap=8
)
ax=cm.bottom_annotation.annotations[2].ax
for side in ["top", "right", "left", "bottom"]:
    ax.set_axis_on()
    ax.spines[side].set_visible(True)
    ax.spines[side].set_color('red')
    ax.spines[side].set_linewidth(1)
    ax.spines[side].set_linestyle('--')
plt.show()
../_images/notebooks_dev_18_0.png

anno_img

[17]:
import matplotlib.image as mpimg
img=mpimg.imread("1.jpeg")
# img=mpimg.imread("2.png")
plt.imshow(img)
print(img.shape)
print(img.T.shape)
(256, 256, 3)
(3, 256, 256)
../_images/notebooks_dev_20_1.png
[18]:
import PIL
import requests
from io import BytesIO
url="https://motifcollections.aertslab.org/v10nr_clust/logos/taipale_cyt_meth__POU5F1_NYTAATTATGCGNRN_FL_meth_repr.png"
response = requests.get(url)
# Open the image from bytes
image = PIL.Image.open(BytesIO(response.content))
# image=PIL.ImageOps.invert(image)
if image.mode != 'RGBA':
    image = image.convert('RGB')
print(image.height,image.width)
image = np.array(image)
plt.imshow(image)
print(image.shape)
print(image.T.shape)
199 399
(199, 399, 3)
(3, 399, 199)
../_images/notebooks_dev_21_1.png

extent

[19]:
img=mpimg.imread("2.png")
plt.xlim(0,500)
plt.ylim(0,300)
plt.imshow(img,extent=[0,240,0,250])
ax=plt.gca()
# ax.invert_yaxis()
print(img.shape)
print(img.T.shape)
(199, 399, 4)
(4, 399, 199)
../_images/notebooks_dev_23_1.png

Direction of imshow: top -> bottom, left -> right The first dimension (height) is Y, the second dimension is X (width)

[20]:
df = pd.DataFrame(['AAAA1'] * 5 + ['BBBBB2'] * 5, columns=['AB'])
df['CD'] = ['C'] * 3 + ['D'] * 3 + ['G'] * 4
df['F'] = np.random.normal(0, 1, 10)
df.index = ['sample' + str(i) for i in range(1, df.shape[0] + 1)]
df_box = pd.DataFrame(np.random.randn(10, 4), columns=['Gene' + str(i) for i in range(1, 5)])
df_box.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar = pd.DataFrame(np.random.uniform(0, 10, (10, 2)), columns=['TMB1', 'TMB2'])
df_bar.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_scatter = pd.DataFrame(np.random.uniform(0, 10, 10), columns=['Scatter'])
df_scatter.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar1 = pd.DataFrame(np.random.uniform(0, 10, (10, 2)), columns=['T1-A', 'T1-B'])
df_bar1.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar2 = pd.DataFrame(np.random.uniform(0, 10, (10, 2)), columns=['T2-A', 'T2-B'])
df_bar2.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar3 = pd.DataFrame(np.random.uniform(0, 10, (10, 2)), columns=['T3-A', 'T3-B'])
df_bar3.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar3.iloc[5,0]=np.nan
df_bar4 = pd.DataFrame(np.random.uniform(0, 10, (10, 1)), columns=['T4'])
df_bar4.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
df_bar4.iloc[7,0]=np.nan
df_img = pd.DataFrame(
    ['https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Python-logo-notext.svg/121px-Python-logo-notext.svg.png',
   'https://motifcollections.aertslab.org/v10nr_clust/logos/metacluster_135.7.png',
   'https://cdn3.iconfinder.com/data/icons/family-member-flat-happy-family-day/512/Brother-512.png',
   'https://cdn3.iconfinder.com/data/icons/family-member-flat-happy-family-day/512/Sister-512.png',
   'https://img.freepik.com/free-vector/sticker-design-with-cute-mouse-isolated_1308-59360.jpg',
   'https://motifcollections.aertslab.org/v10nr_clust/logos/metacluster_131.8.png',
   'https://img.freepik.com/premium-vector/vector-illustration-gorilla-isolated-white-background-cartoon-style_1151-66575.jpg',
  "2.png",'1.jpeg',
  'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Python-logo-notext.svg/121px-Python-logo-notext.svg.png'],
    columns=['path'])
# df_img = pd.DataFrame(
#     ["2.png",'1.jpeg']*5, columns=['path'])
df_img.index = ['sample' + str(i) for i in range(1, df_box.shape[0] + 1)]
[21]:
plt.figure(figsize=(10, 5))
col_ha = HeatmapAnnotation(
            label=anno_label(df.AB, merge=True,rotation=15),
            AB=anno_simple(df.AB,add_text=True,legend=True), axis=1,
            CD=anno_simple(df.CD, add_text=True,legend=True,text_kws={'color':'black'}),
            Exp=anno_boxplot(df_box, cmap='turbo',legend=True),
            Scatter=anno_scatterplot(df_scatter),
            Bar1=anno_barplot(df_bar1,legend=True,cmap='Dark2'),
            Bar4=anno_barplot(df_bar4,legend=True,cmap='turbo'),
            Img=anno_img(df_img.path),
            plot=True,legend=True,legend_gap=5,hgap=0.5)
col_ha.show_ticklabels(df.index.tolist(),fontdict={'color':'blue'},rotation=-30)
plt.show()
Starting plotting HeatmapAnnotations
Collecting annotation legends..
../_images/notebooks_dev_26_1.png
[22]:
plt.figure(figsize=(8, 6))
col_ha = HeatmapAnnotation(
            AB=anno_simple(df.AB,add_text=True,legend=True),
            CD=anno_simple(df.CD, add_text=True,legend=True,text_kws={'color':'black'}),
            Exp=anno_boxplot(df_box, cmap='turbo',legend=True),
            Scatter=anno_scatterplot(df_scatter),
            Bar1=anno_barplot(df_bar1,legend=True,cmap='Dark2'),
            Img=anno_img(df_img.path),
            Bar4=anno_barplot(df_bar4,legend=True,cmap='turbo'),
            plot=True,legend=True,legend_gap=5,hgap=0.5, axis=0,orientation='right',legend_hpad=15)
col_ha.show_ticklabels(df.index.tolist(),fontdict={'color':'blue'}) #rotation

ax=col_ha.annotations[-2].ax
ax.xaxis.set_visible(True) # show ticks
ax.tick_params(
    axis="x", which="both", bottom=True, labelbottom=True
)
for side in ["top", "right", "left", "bottom"]:
    ax.set_axis_on()
    ax.spines[side].set_visible(True)
    ax.spines[side].set_color('red')
    ax.spines[side].set_linewidth(1)
    ax.spines[side].set_linestyle('--')
plt.show()
Starting plotting HeatmapAnnotations
Collecting annotation legends..
../_images/notebooks_dev_27_1.png
[23]:
plt.figure(figsize=(8, 6))
col_ha = HeatmapAnnotation(
            Img=anno_img(df_img.path),
            AB=anno_simple(df.AB,add_text=True,legend=True),
            CD=anno_simple(df.CD, add_text=True,legend=True,text_kws={'color':'black'}),
            Exp=anno_boxplot(df_box, cmap='turbo',legend=True),
            Scatter=anno_scatterplot(df_scatter),
            Bar1=anno_barplot(df_bar1,legend=True,cmap='Dark2'),
            Bar4=anno_barplot(df_bar4,legend=True,cmap='turbo'),
            plot=True,legend=True,legend_gap=5,hgap=0.5, axis=0,orientation='left',legend_hpad=15)
col_ha.show_ticklabels(df.index.tolist(),fontdict={'color':'blue'}) #rotation
ax=col_ha.annotations[0].ax
ax.xaxis.set_visible(True) # show ticks
ax.tick_params(
    axis="x", which="both", bottom=True, labelbottom=True
)
for side in ["top", "right", "left", "bottom"]:
    ax.set_axis_on()
    ax.spines[side].set_visible(True)
    ax.spines[side].set_color('red')
    ax.spines[side].set_linewidth(1)
    ax.spines[side].set_linestyle('--')
plt.show()
Starting plotting HeatmapAnnotations
Collecting annotation legends..
../_images/notebooks_dev_28_1.png

Color palette design

[269]:
import matplotlib.pyplot as plt
import colorsys
import numpy as np
from matplotlib import colors as mcolors
named_colors=mcolors.CSS4_COLORS
named_colors.update(mcolors.BASE_COLORS) #kes is color string, values are hex
# named_colors.update(mcolors.TABLEAU_COLORS)
named_colors.update(mcolors.CSS4_COLORS)
for k in named_colors:
    if isinstance(named_colors[k],tuple):
        named_colors[k]=mcolors.to_hex(named_colors[k])

def identify_color_format(color):
    if color in named_colors:
        return 'named_color'
    # Check if the color is in HEX format (e.g., #RRGGBB or #RGB)
    elif isinstance(color, str) and color.startswith('#'):
        if len(color) == 7 or len(color) == 4:
            return 'HEX'
    # Check if the color is in RGB format (tuple of 3 integers/floats)
    elif isinstance(color, tuple) and len(color) == 3:
        if all(isinstance(val, int) and 0 <= val <= 255 for val in color):
            return 'RGB (integer)'
        elif all(isinstance(val, float) and 0 <= val <= 1 for val in color):
            return 'RGB (float)'
    # Check if the color is in HLS format (tuple of 3 floats)
    elif isinstance(color, tuple) and len(color) == 3:
        h, l, s = color
        if (isinstance(h, float) and 0 <= h <= 1) or (isinstance(h, int) and 0 <= h <= 360):
            if isinstance(l, float) and 0 <= l <= 1 and isinstance(s, float) and 0 <= s <= 1:
                return 'HLS'
    return 'Unknown'


def generate_similar_colors(base_color, num_colors=5, h_delta=1/6, l_delta=0.4, s_delta=0.4,
                           l_min=0.2,l_max=0.8,s_min=0.2,s_max=0.8):
    fmt=identify_color_format(base_color)
    if not fmt.startswith('RGB'):
        base_color=mcolors.to_rgb(base_color)

    # Convert the base RGB color to HLS (Hue, Lightness, Saturation)
    r, g, b = base_color
    h, l, s = colorsys.rgb_to_hls(r, g, b)

    # Generate a list of similar colors by varying the hue
    # The hue determines the "base" color:
    #     0 or 1 (or 360 degrees) = Red
    #     1/6 (or 60 degrees) = Yellow
    #     2/6 (or 120 degrees) = Green
    #     3/6 (or 180 degrees) = Cyan
    #     4/6 (or 240 degrees) = Blue
    #     5/6 (or 300 degrees) = Magenta
    #     Back to Red as it cycles around the wheel.
    colors = []
    hues=np.linspace(max(h-h_delta,0),min(h+h_delta,1),num_colors)
    lightness=np.linspace(max(l-l_delta,l_min),min(l+l_delta,l_max),num_colors)
    saturations=np.linspace(max(s-s_delta,s_min),min(s+s_delta,s_max),num_colors)
    for h1,l1,s1 in zip(hues,lightness,saturations):
        new_color = colorsys.hls_to_rgb(h1, l1, s1)
        colors.append(new_color)
    return colors

def interpolate_colors(color1, color2, num_colors,fmt='rgb'):
    if fmt=='hls':
        color1=colorsys.hls_to_rgb(*color1)
        color2=colorsys.hls_to_rgb(*color2)
    elif fmt!='rgb':
        color1=mcolors.to_rgb(color1)
        color2=mcolors.to_rgb(color2)
    # Convert colors to numpy arrays for easy interpolation
    color1 = np.array(color1)
    color2 = np.array(color2)

    # Generate a linear interpolation between the two colors
    colors = [tuple(color1 + (color2 - color1) * i / (num_colors - 1)) for i in range(num_colors)]

    return colors

def generate_quantive_colors(color,n=5,white=(0.9,0.9,0.9),black=(0.3,0.3,0.3),ret_fmt='hex'):
    fmt=identify_color_format(color)
    if not fmt.startswith('RGB'):
        color=mcolors.to_rgb(color)
    light_colors=interpolate_colors(white,color,n//2 + 2)[1:-1] # from white to color
    dark_colors=interpolate_colors(color,black,n//2 + 2)[1:-1] # from color to black;white=(1,1,1),black=(0,0,0)
    if len(light_colors)+len(dark_colors) == n:
        results=light_colors+dark_colors
    else:
        results=light_colors+[color]+dark_colors
    if ret_fmt=='rgb':
        return results
    elif ret_fmt=='hex':
        return [mcolors.to_hex(c) for c in results]
[236]:
# Step 3: Plot the generated colors
def plot_colors(colors):
    fig, ax = plt.subplots(1, figsize=(10, 1), subplot_kw=dict(xticks=[], yticks=[]))
    for i, color in enumerate(colors):
        ax.add_patch(plt.Rectangle((i, 0), 1, 1, color=color))
    plt.xlim(0, len(colors))
    plt.show()
[238]:
similar_colors = generate_similar_colors('red', num_colors=10) ## Light blue
# Plot the generated similar colors
plot_colors(similar_colors)
../_images/notebooks_dev_32_0.png
[242]:
similar_colors=interpolate_colors('red','white',3,fmt='named_color')
plot_colors(similar_colors)
../_images/notebooks_dev_33_0.png
[270]:
similar_colors=generate_quantive_colors('orange',n=10)
plot_colors(similar_colors)
../_images/notebooks_dev_34_0.png
[271]:
similar_colors=generate_quantive_colors('blue',n=5)
plot_colors(similar_colors)
../_images/notebooks_dev_35_0.png
[272]:
similar_colors=generate_quantive_colors('skyblue',n=5)
plot_colors(similar_colors)
../_images/notebooks_dev_36_0.png
[273]:
similar_colors=generate_quantive_colors('green',n=5)
plot_colors(similar_colors)
../_images/notebooks_dev_37_0.png
[274]:
similar_colors
[274]:
['#99c499', '#4da24d', '#008000', '#196f19', '#335e33']
[263]:
plot_colors([(1,1,1),(0.9,0.9,0.9),(0.4,0.4,0.4),(0.3,0.3,0.3),(0.2,0.2,0.2),(0,0,0)])
../_images/notebooks_dev_39_0.png
[130]:
mcolors.to_rgb(())
[130]:
(1.0, 0.0, 0.0)
[247]:
mcolors.to_rgb('black')
[247]:
(0.0, 0.0, 0.0)
[128]:
colorsys.rgb_to_hls(*mcolors.to_rgb('red'))
[128]:
(0.0, 0.5, 1.0)
[129]:
colorsys.rgb_to_hls(*mcolors.to_rgb('pink'))
[129]:
(0.9708994708994709, 0.8764705882352941, 1.0)
[267]:
mcolors.to_hex((0.0, 0.0, 0.0))
[267]:
'#000000'