以下代码使用本机 Matplotlib 表生成您想要的图形的近似值:
import matplotlib.pylab as plt
import numpy as np
def get_coord(table, irow, icol):
# get coordinates of a cell. This seems to work, don't ask why.
cell = table.get_celld()[irow+1,icol] # row 0 is column headers
box = cell.get_bbox().get_points() # [[x0, y0],[x1, y1]]
xc, yc = box.mean(axis=0) # get center
return xc, yc
col_labels=['G','A','T','C','C']
row_labels= ['G','T','G','C','C']
table_vals= [
['x','','','',''],
['','','x','',''],
['x','','','',''],
['','','','x','x'],
['','','','x','x']]
line = [(0,0), (0,1), (1,2), (2,2), (3,3), (4,4)]
# draw table
the_table = plt.table(cellText=table_vals,
colWidths = [0.1]*len(col_labels),
rowLabels=row_labels, colLabels=col_labels,
cellLoc = 'center', rowLoc = 'center', bbox=[.1,.1,.8,.8])
plt.draw() # lay out table, so that cell coordinates are calculated
# look up line coordinates
x = []; y = []
for irow, icol in line:
xc, yc = get_coord(the_table, irow, icol)
x.append(xc)
y.append(yc)
# draw line
plt.plot(x, y, 'r', linewidth = 5, alpha=0.5)
plt.xlim([0,1])
plt.ylim([0,1])
plt.show()
Result:
请注意,结果并不是非常漂亮,例如,我无法弄清楚如何使用行标签更改列的宽度。还有一个问题是表格是在“图形坐标”中绘制的,而线条是在“数据坐标”中绘制的,因此如果放大线条,表格将不再重叠。我在这些表上挣扎了相当长的时间,但在我看来,它们非常适合使用 PITA,而且生成的代码很难理解。
我首选的解决方案是手动绘制表格:
import matplotlib.pylab as plt
import numpy as np
col_labels=['G','A','T','C','C']
row_labels= ['G','T','G','C','C']
table_vals= [
['X','','','',''],
['','','X','',''],
['X','','','',''],
['','','','X','X'],
['','','','X','X']]
line = np.array([
[0, 1, 2, 2, 3, 4],
[0, 0, 1, 2, 3, 4]])
ncol = len(col_labels)
nrow = len(row_labels)
# draw grid lines
plt.plot(np.tile([0, ncol+1], (nrow+2,1)).T, np.tile(np.arange(nrow+2), (2,1)),
'k', linewidth=3)
plt.plot(np.tile(np.arange(ncol+2), (2,1)), np.tile([0, nrow+1], (ncol+2,1)).T,
'k', linewidth=3)
# plot labels
for icol, col in enumerate(col_labels):
plt.text(icol + 1.5, nrow + 0.5, col, ha='center', va='center')
for irow, row in enumerate(row_labels):
plt.text(0.5, nrow - irow - 0.5, row, ha='center', va='center')
# plot table content
for irow, row in enumerate(table_vals):
for icol, cell in enumerate(row):
plt.text(icol + 1.5, nrow - irow - 0.5, cell, ha='center', va='center')
# plot line
plt.plot(line[0] + 1.5, nrow - line[1] - 0.5, 'r', linewidth = 5, alpha = 0.5)
plt.axis([-0.5, ncol + 1.5, -0.5, nrow+1.5])
plt.show()
结果:
这看起来好多了,而且代码也很容易理解。您可能想根据自己的喜好调整一些线宽和字体大小,并隐藏轴。