我使用Python软件包Seaborn将矩阵绘制为PDF文档的热图,每个热图都在一个单独的页面上。热图具有相同的列数(在一次运行中相同,但通常不是常量)并且可能有不同的行数,因此PDF页面的大小不同。我希望在整个PDF文档中将热映射单元格成为相同大小的正方形。理想情况下,我会在绘制热图时明确指定单元格大小,但似乎没有这样的选项。我尝试按比例调整图表的行数和列数,但即使对于常量figure_width
和figure_height = cell_size * row_count
,它也不会导致固定cell_size
的单元格,而figure_width = cell_size * column_count
并且figure_height = cell_size * row_count
还会在热图的宽度和高度之间产生相互作用(因为单元格是正方形,即纵横比为1:1),结果比例变得更加模糊。
是否有任何解决方案可以明确指定seaborn.heatmap(或matplotlib colorbar,colormesh等)中的单元格大小,或者强制将其强制为某个值?
figure_width
为常数(20英寸)和figure_height = cell_size * row_count
(cell_size
为0.2英寸)时的代码,生成最后一张热图(单元格高度为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_count
和figure_height = cell_size * row_count
(cell_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文档中保持不变,而在整个运行过程中都会发生变化。
答案 0 :(得分:2)
您需要计算一些参数才能获得所需的结果 您可以从图形宽度开始。然后在热图周围定义一些边距和行数(应该是常量) 从这些数字中,您可以计算一次单元格(像素)的英寸大小 然后,对于每个图,您可以计算托管一定数量单元格所需的图形高度。这是在循环内完成的。此外,每个数字都需要设置相对边距(从绝对值计算)。
最后这会给出(忽略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