DingWB / PyComplexHeatmap

PyComplexHeatmap: A Python package to plot complex heatmap (clustermap)
https://dingwb.github.io/PyComplexHeatmap/
MIT License
295 stars 32 forks source link

anno_simple colors are wrong #32

Closed Laolga closed 1 year ago

Laolga commented 1 year ago

I want to plot 22 groups on top of my heatmap with light and dark grey. For the colors argument I'm using the following dictionary:

{1: '#999993',
 2: '#eeeee4',
 3: '#999993',
 4: '#eeeee4',
 5: '#999993',
 6: '#eeeee4',
 7: '#999993',
 8: '#eeeee4',
 9: '#999993',
 10: '#eeeee4',
 11: '#999993',
 12: '#eeeee4',
 13: '#999993',
 14: '#eeeee4',
 15: '#999993',
 16: '#eeeee4',
 17: '#999993',
 18: '#eeeee4',
 19: '#999993',
 20: '#eeeee4',
 21: '#999993',
 22: '#eeeee4'}

And then plot the heatmap like this:

plt.figure(figsize=(10, 5))

cols = HeatmapAnnotation(chromosome = anno_simple(cut_chroms.chromosome,add_text=True, colors = colors, text_kws ={"color": "black"} )
                         ,plot_legend = True,axis = 1,plot = False)
cm1 = ClusterMapPlotter(data=hm,row_dendrogram=True,show_rownames=False,show_colnames=False,top_annotation = cols,
                       row_cluster_metric = "euclidean",col_cluster = False,
                      row_cluster = True, label='Expression')

plt.show()

image As you see, in the initial dictionary group 16 was supposed to be light grey (unlike 15 and 17) and you can also see that in the legend it's light grey, but in the heatmap it's dark grey. Could you please suggest what might be an issue?

DingWB commented 1 year ago

Could you please upload the data you used so I can debug it?

DingWB commented 1 year ago

Could you let me know if you solved this issue?

tyamadat commented 1 year ago

Hi, I have encountered the same issue in my script. Apparently this happens when the number of the annotation is >= 22. In my case, the color of the 13th and 14th annotations should be distinct, but they are both plotted in the 13th annotation color, although the legend looks normal. I am wondering if you have any idea to fix this. Thank you in advance.

DingWB commented 1 year ago

Could you please try to use cmap='cmap50' and rerun it? The default colormap, such as Set1 and Dark2, only has 10 different kinds of color; cmap50 is a custom colormap in PyComplexHeatmap.

tyamadat commented 1 year ago

Thank you for your reply. When I use cmap='cmap50', it works. Yet, when I pass colors by colors= with a dictionary that has >22 elements, it doesn't.

DingWB commented 1 year ago

That's weird. Let me find the reason and fix it.

DingWB commented 1 year ago

I found the bug and fixed it. Please update to the newest version (1.5.2) and try again. @tyamadat @Laolga

DingWB commented 1 year ago

Here is an example to test:

colors={}

for i in range(1,23):
    c='#eeeee4' if i %2 ==0 else '#999993'
    colors['chr'+str(i)]=c
print(colors)

cut_chroms=pd.DataFrame(['chr'+str(i) for i in range(1,23)],columns=['chromosome'])
cut_chroms.chromosome=cut_chroms.chromosome.map(str)

plt.figure(figsize=(12, 5))
col_ha = HeatmapAnnotation(chromosome = anno_simple(cut_chroms.chromosome,colors = colors,add_text=True,text_kws={'rotation':90,'fontsize':8,'color':'black'}),
                         plot=True,plot_legend = True,axis = 1)
plt.show()

image

DingWB commented 1 year ago

I checked again. It works on my side. Did you upgrade to 1.5.2? Try:

pip install --upgrade PyComplexHeatmap

You can run

import PyComplexHeatmap
print(PyComplexHeatmap.__version__)

to print your version. It should be 1.5.2. Please keep me posted.

tyamadat commented 1 year ago

Sorry to bother you. I checked the commit record thoroughly, and I missed some commits. Now I can plot your example correctly. I really appreciate your support, and thank you so much for developing such a great package!

Screenshot from 2023-07-11 21-04-41