具有固定网格尺寸的多个热图

时间:2017-03-02 17:50:05

标签: python-3.x matplotlib seaborn

我正在使用seaborn(v.0.7.1)和matplotlib(1.5.1)以及pandas(v.0.18.1)来绘制不同的数据集群不同大小作为for循环内的热图,如下面的代码所示。

我的问题是,由于每个群集包含不同数量的行,因此最终的数字具有不同的大小(即热图中每个框的高度和宽度在不同的热图上是不同的)(见图)。最后,我希望有相同大小的数字(如上所述)。

我检查了seabornmatplotlib文档的某些部分以及stackoverflow,但由于我不知道确切的关键字要查找的内容(如问题标题所示)我无法找到任何答案。 [编辑:现在我已根据@ImportanceOfBeingErnest的建议更新了标题。之前的标题是:“在多个图表中强制执行相同的宽度”。]

import numpy as np
import pandas as pd
clusters = pd.DataFrame([(1,'aaaaaaaaaaaaaaaaa'),(1,'b'), (1,'c'), (1,'d'), (2,'e'), (2,'f')])
clusters.columns = ['c', 'p']
clusters.set_index('c', inplace=True)
g = pd.DataFrame(np.ones((6,4)))
c= pd.DataFrame([(1,'aaaaaaaaaaaaaaaaa'),(2,'b'), (3,'c'), (4,'d'), (5,'e'), (6,'f')])
c.columns = ['i', 'R'] 
for i in range(1,3,1):
     ee = clusters[clusters.index==i].p
     inds = []
     for v in ee:
         inds.append(np.where(c.R.values == v)[0][0])
     f, ax = plt.subplots(1, figsize=(13, 15))
     ax = sns.heatmap(g.iloc[inds],  square=True, ax=ax, cbar=True, linewidths=2, linecolor='k', cmap="Reds",  cbar_kws={"shrink": .5},
        vmin = math.floor(g.values.min()), vmax =math.ceil(g.values.max())) 
     null = ax.set_xticklabels(['a', 'b', 'c', 'd'], fontsize=15)
     null = ax.set_yticklabels(c.R.values[inds][::-1], fontsize=15, rotation=0)
     plt.tight_layout(pad=3)

[ EDIT ]:现在我添加了一些代码来创建@Brian建议的最小功能示例。现在我注意到这个问题可能是由文本造成的!

enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

在以下条件下

  1. 如果只保存图片中的方块尺寸相同,我们不关心屏幕上的情节
  2. 我们可以省略colorbar
  3. 解决方案相当直接。

    可以定义一个正方形在最终图像squaresize = 50中应该具有的尺寸,找出每个尺寸(nm)中要绘制的正方形的数量并调整数字大小为

    figwidth = m*squaresize/float(dpi)
    figheight = n*squaresize/float(dpi)
    

    其中dpi表示每英寸像素数。

    import numpy as np
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    dpi=100
    squaresize = 50 # pixels
    
    n = 3
    m = 4
    
    data = np.random.rand(n,m)
    figwidth = m*squaresize/float(dpi)
    figheight = n*squaresize/float(dpi)
    f, ax = plt.subplots(1, figsize=(figwidth, figheight), dpi=dpi)
    f.subplots_adjust(left=0, right=1, bottom=0, top=1)
    
    ax = sns.heatmap(data, square=True, ax=ax, cbar=False)
    plt.savefig(__file__+".png", dpi=dpi, bbox_inches="tight")
    

    bbox_inches="tight"确保仍然绘制标签等(即最终的图形尺寸将大于此处计算的尺寸,具体取决于标签需要多少空间)。 要将此示例应用于您的案例,您仍需要根据数据框找出热图中有多少行和列,但由于我没有它的结构,因此很难提供一般解决方案。