首页 文章

缩放不同尺寸的热图以使细胞大小相等

提问于
浏览
1

我正在使用Python包Seaborn将矩阵绘制为PDF文档的热图,每个热图都在一个单独的页面上 . 热图具有相同的列数(在一次运行中相同,但通常不是常数),并且可能有不同的行数,因此PDF页面的大小不同 . 我希望在整个PDF文档中将单元格映射为相同大小的正方形 . 理想情况下,我会在绘制热图时明确指定单元格大小,但似乎没有这样的选项 . 我尝试按比例调整图形的行数和列数,但即使对于常量 figure_widthfigure_height = cell_size * row_count ,它也不会导致固定 cell_size 的单元格,而 figure_width = cell_size * column_countfigure_height = cell_size * row_count 另外会在热图的宽度和高度之间产生相互作用(因为单元格是正方形的) ,即纵横比为1:1),得到的比例变得更加模糊 .

是否有任何解决方案可以明确指定seaborn.heatmap(或matplotlib colorbar,colormesh等)中的单元格大小,或者强制将其强制为某个值?

我的代码 figure_width 是常数(20in)和 figure_height = cell_size * row_countcell_size 是0.2in),产生最后一个热图(高度为5个单元格),单元格大小与其余不同:

from matplotlib.backends.backend_pdf import PdfPages
import seaborn
import numpy as np

with PdfPages('test.pdf') as pdf_pages:
    column_count = 150
    for row_count in [100, 30, 10, 5]:
        data = np.random.rand(row_count, column_count)
        fig = plt.figure(figsize=(20, 0.2 * row_count))
        seaborn.heatmap(data, square=True, xticklabels=range(column_count),
                             yticklabels=range(row_count), cbar=None)
        plt.tight_layout()
        pdf_pages.savefig(fig)

figure_width = cell_size * column_countfigure_height = cell_size * row_countcell_size 为0.2in)时的代码,生成具有不同单元大小的所有热图:

with PdfPages('test.pdf') as pdf_pages:
    column_count = 150
    for row_count in [100, 30, 10, 5]:
        data = np.random.rand(row_count, column_count)
        fig = plt.figure(figsize=(0.2 * column_count, 0.2 * row_count))
        seaborn.heatmap(data, square=True, xticklabels=range(column_count),
                             yticklabels=range(row_count), cbar=None)
        plt.tight_layout()
        pdf_pages.savefig(fig)

理想情况下,解决方案应该是 column_count 的参数化,因为它只在一个PDF文档中保持不变,而在整个运行过程中都会发生变化 .

1 回答

  • 1

    您需要计算一些参数以获得所需的结果 .
    您可以从图形宽度开始 . 然后在热图周围定义一些边距和行数(应该是常量) .
    从这些数字中,您可以计算一次单元格(像素)的英寸大小 .
    然后,对于每个图,您可以计算托管一定数量单元格所需的图形高度 . 这是在循环内完成的 . 此外,每个数字都需要设置相对边距(从绝对值计算) .

    最后这将给出(忽略pdfpages,这似乎与此无关):

    import matplotlib.pyplot as plt
    import seaborn
    import numpy as np
    
    ####  Free input parameters ####
    cols = [100, 30, 10, 5]
    # start by specifying figure width and margins
    figwidth= 20. #inch
    marg_top = 0.7
    marg_bottom = 0.7
    marg_left = 0.7
    marg_right = 0.7
    
    # number of cells along width
    cells_in_row = 150
    
    ####  Automatic calculation ####
    # determine cell size in inch
    cellsize = (figwidth-marg_left-marg_right)/float(cells_in_row)
    # now loop over cols:
    for cells_in_column in cols:
        # calculate figure height in inches
        figheight = cellsize*cells_in_column+marg_top+marg_bottom
        # set figure size
        fig = plt.figure(figsize=(figwidth, figheight))
        # adjust margins (relative numbers) according to absolute values
        fig.subplots_adjust(bottom =marg_bottom/figheight ,top=1.-marg_top/figheight,
                            left=marg_left/figwidth, right=1.-marg_right/figwidth)
    
        data = np.random.rand(cells_in_column, cells_in_row)
        seaborn.heatmap(data, square=True, xticklabels=range(cells_in_row),
                             yticklabels=range(cells_in_column), cbar=None)
        fig.savefig("fig{}.png".format(cells_in_column))
    

    当然你也可以从给定的 cellsize 开始并从中计算出图形宽度:

    # start by specifying cell size and margins
    cellsize = 0.08 #inch
    marg_top = 0.7
    marg_bottom = 0.7
    marg_left = 0.7
    marg_right = 0.7
    
    # number of cells along width
    cells_in_row = 150
    # determine figure width
    figwidth = cellsize* cells_in_row + marg_left+marg_right
    

相关问题