在seaborn热力图中控制单个线条的宽度

6

有没有可能在seaborn热力图中为特定的列和行扩大线宽呢?

例如,这个热力图可以吗

import numpy as np; np.random.seed(0)
import seaborn as sns; sns.set()
uniform_data = np.random.rand(10, 12)
ax = sns.heatmap(uniform_data, linewidths=1.0)

可将其转化为以下形式:

enter image description here


今天稍晚时候也有一个类似的问题被问到了,链接在这里:https://dev59.com/Q6Dia4cB1Zd3GeqPDGr4。 - ImportanceOfBeingErnest
1个回答

8

这是有可能的,但需要花费大量的工作。一种可能的解决方案如下所示。它涉及绘制6个不同的热图,并调整间距使其看起来还可以。然后还需要同步颜色缩放并手动设置色条。

import matplotlib
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
import seaborn as sns; sns.set()

data = np.random.rand(10, 12)

asp = data.shape[0]/float(data.shape[1])
figw = 8
figh = figw*asp

cmap = plt.cm.copper
norm = matplotlib.colors.Normalize(vmin= data.min(), vmax= data.max())

gridspec_kw = {"height_ratios":[9,1], "width_ratios" : [4,5,3]}
heatmapkws = dict(square=False, cbar=False, cmap = cmap, linewidths=1.0, vmin= data.min(), vmax= data.max() ) 
tickskw =  dict(xticklabels=False, yticklabels=False)

left = 0.07; right=0.87
bottom = 0.1; top = 0.9
fig, axes = plt.subplots(ncols=3, nrows=2, figsize=(figw, figh), gridspec_kw=gridspec_kw)
plt.subplots_adjust(left=left, right=right,bottom=bottom, top=top, wspace=0.1, hspace=0.1*asp )
sns.heatmap(data[:9,0:4], ax=axes[0,0], xticklabels=False, yticklabels=True, **heatmapkws)
sns.heatmap(data[:9,4:9], ax=axes[0,1], xticklabels=False, yticklabels=False, **heatmapkws)
sns.heatmap(data[:9,9:12], ax=axes[0,2],xticklabels=False, yticklabels=False, **heatmapkws)

sns.heatmap(data[9:,:4], ax=axes[1,0], xticklabels=True, yticklabels=True, **heatmapkws)
sns.heatmap(data[9:,4:9], ax=axes[1,1], xticklabels=True, yticklabels=False, **heatmapkws)
sns.heatmap(data[9:,9:12], ax=axes[1,2], xticklabels=True, yticklabels=False,**heatmapkws)

axes[1,0].set_yticklabels([9])
axes[1,1].set_xticklabels([4,5,6,7,8])
axes[1,2].set_xticklabels([9,10,11])

cax = fig.add_axes([0.9,0.1,0.03,0.8])
sm = matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
fig.colorbar(sm, cax=cax)

plt.show()

enter image description here


这是正确的答案(尽管代码可以更干净,通过使用for循环而不是复制调用sns.heatmap。) - mwaskom
@mwaskom 是的,代码可能会变得更加简洁,但是可能会变得不太容易理解,因为循环需要控制4个不同的numpy索引以及x和y刻度标签的切换。现在,刻度标签可以在循环外部设置,但这使得更难以获得刻度默认状态在像素中间的状态。这就是为什么我决定不这样做的原因。我认为任何人都可以将上述解决方案适应到循环中,而不是理解循环。最烦人的是正确的纵横比的调整 - 顺便说一下,这里并不完美。 - ImportanceOfBeingErnest
再次感谢你,Ernes。你真是帮了我大忙。我可以用那个工作! - Pat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接