更改 Seaborn 热点地图的蜱标签旋转

我正在绘制 Seaborn 的热点地图。问题是在我的绘图中有太多的正方形,所以 x 和 y 标签彼此太接近而没有用处。所以我创建了一个 xticks 和 yticks 的列表来使用。但是,将此列表传递给函数会在绘图中旋转标签。这将是非常好的,有海运自动下降一些壁虱,但除非,我希望能够有壁虱直立。

import pandas as pd
import numpy as np
import seaborn as sns


data = pd.DataFrame(np.random.normal(size=40*40).reshape(40,40))


yticks = data.index
keptticks = yticks[::int(len(yticks)/10)]
yticks = ['' for y in yticks]
yticks[::int(len(yticks)/10)] = keptticks


xticks = data.columns
keptticks = xticks[::int(len(xticks)/10)]
xticks = ['' for y in xticks]
xticks[::int(len(xticks)/10)] = keptticks


sns.heatmap(data,linewidth=0,yticklabels=yticks,xticklabels=xticks)

enter image description here

84227 次浏览

seaborn在内部使用 matplotlib,因此您可以使用 matplotlib函数来修改您的绘图。我已经修改了下面的代码,使用 plt.yticks函数设置 rotation=0来修复这个问题。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns




data = pd.DataFrame(np.random.normal(size=40*40).reshape(40,40))


yticks = data.index
keptticks = yticks[::int(len(yticks)/10)]
yticks = ['' for y in yticks]
yticks[::int(len(yticks)/10)] = keptticks


xticks = data.columns
keptticks = xticks[::int(len(xticks)/10)]
xticks = ['' for y in xticks]
xticks[::int(len(xticks)/10)] = keptticks


sns.heatmap(data,linewidth=0,yticklabels=yticks,xticklabels=xticks)


# This sets the yticks "upright" with 0, as opposed to sideways with 90.
plt.yticks(rotation=0)


plt.show()

Plot

也可以调用 Heat map 对象的方法:

    g = sns.heatmap(data,linewidth=0,yticklabels=yticks,xticklabels=xticks)
g.set_yticklabels(g.get_yticklabels(), rotation = 0, fontsize = 8)

我不确定为什么 sns.heatmap 的文档中没有这个,但是这里描述了相同的方法: http://seaborn.pydata.org/generated/seaborn.FacetGrid.html

我相信这些方法对于每个海运图对象都是可用的,但是找不到一个通用的 API。

在上述问题的基础上,我找到了一个类似问题的解决方案,即旋转轴上刻度的值。

我遇到的问题是通过 Seaborn 和 FacetGrid 使用 Heatmap。我可以旋转 x 轴的刻度,但是 y 轴的刻度不能用..。

for ax in fg.axes.flat:
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
ax.set_yticklabels(ax.get_yticklabels(), rotation=45)

我发现扁虱是空白的,最后被一个空名单取代了。这是因为列包装 col_wrap中的最终数据没有 yticks,因为我将它们排列在左侧,所以第0和第2 yticks 被我的2x2网格矩阵中的第1和第3 yticks 覆盖。Xticks 没有这个问题,因为 xtick 值是相反的,第0和第2个 xticks 为 null,而第1和第3个 xticks 有值。我通过打印 g.get_yticklabels()发现了这个特性:

g = sns.heatmap(d, **kwargs)
print(g.get_yticklabels())
[Text(0, 0.5, '5'), Text(0, 1.5, '8'), Text(0, 2.5, '12'), Text(0, 3.5, '15'), Text(0, 4.5, '19'), Text(0, 5.5, '22'), Text(0, 6.5, '25'), Text(0, 7.5, '26'), Text(0, 8.5, '29'), Text(0, 9.5, '33'), Text(0, 10.5, '34'), Text(0, 11.5, '36'), Text(0, 12.5, '40'), Text(0, 13.5, '43'), Text(0, 14.5, '47')]
[]
[Text(0, 0.5, '1'), Text(0, 1.5, '5'), Text(0, 2.5, '8'), Text(0, 3.5, '12'), Text(0, 4.5, '15'), Text(0, 5.5, '19'), Text(0, 6.5, '22'), Text(0, 7.5, '25'), Text(0, 8.5, '26'), Text(0, 9.5, '29'), Text(0, 10.5, '33'), Text(0, 11.5, '34'), Text(0, 12.5, '36'), Text(0, 13.5, '40'), Text(0, 14.5, '43'), Text(0, 15.5, '47')]
[]

我的解决办法是,只有在 {x,y}tick出现的情况下才能执行这两个轮换:

g = sns.heatmap(d, **kwargs)
if g.get_yticklabels():
g.set_yticklabels(g.get_yticklabels(), rotation=30)
if g.get_xticklabels():
g.set_xticklabels(g.get_xticklabels(), rotation=45)

这在循环函数中执行,然后映射到 FacetGrid。这假设 {x,y}ticks对于所有四个图都是等价的。

def draw_heatmap(*args, **kwargs):
data = kwargs.pop('data')
d = data.pivot(index=args[1], columns=args[0], values=args[2])
# High-Low limit values
hl = args[3]
lwrbnd, uprbnd = data[args[2]].describe([hl,1-hl]).iloc[[4,6]].values
g = sns.heatmap(d, **kwargs, vmin=lwrbnd, vmax=uprbnd)
if g.get_yticklabels():
g.set_yticklabels(labels=g.get_yticklabels(), rotation=30)
if g.get_xticklabels():
g.set_xticklabels(g.get_xticklabels(), rotation=45)


fg = sns.FacetGrid(multidf.groupby(findx).mean().reset_index(),
col_wrap=col_wrp, col=ondx, height=5, sharey=True)
fg.map_dataframe(draw_heatmap, 'col', 'row', toggle, hl, square=True,
cmap="YlGnBu")