The following code yields an approximation of the figure you want, using native Matplotlib tables:
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:

Note that the result is not extremely beautiful, I could for example not figure out how to change the width of the column with row-labels. There is also the issue that the table is drawn in 'figure coordinates', while the line is drawn in 'data-coordinates', so if you zoom in the line and the table no longer overlap. I struggled for quite some time with these tables, but in my opinion they are quite a PITA to work with and the resulting code is hard to understand.
My preferred solution is to just draw the table by hand:
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()
with result:

This looks much nicer, and the code is straightforward to understand. You might want to adjust some line-widths and font-sizes to your own taste, and hide the axis.
imshow(), create custom labels for the axes and then draw that line above all.