在 matplotlib 中绘制 Needleman-Wunsch 成对序列比对的得分矩阵
Plotting the score matrix from a Needleman-Wunsch pairwise sequence alignment in matplotlib
我正在尝试根据 Python 中的全局对齐算法(或 Needleman–Wunsch algorithm)绘制矩阵。
我不知道 matplotlib 是否是这种情况下的最佳工具。我尝试使用 Bokeh 但该结构很难按照我的意愿适合矩阵。
我正在使用 Bio.SeqIO(BioPython 的标准序列 Input/Output 接口)来存储两个序列。
我怎样才能得到类似于这张图片的结果:
在 Matplotlib 中可以吗?我该怎么做?
更新
最后,我能够根据 ImportanceOfBeingErnest 给出的答案构建算法。这是结果:
这里是这个实现的要点:plot_needleman_wunsch.py
这是整个项目(进行中的工作):bmc-sequence-alignment
问题中没有明确说明放置箭头的算法;因此,这个答案侧重于在 matplotlib 中生成类似图的方法。
这里的想法是将数字放在图中的整数位置,并在 n+0.5
处绘制次网格线以获得类似 table 的外观。箭头绘制为 4 列数组中定义的位置之间的注释(前 2 列:箭头起点的 x 和 y,第三和第四列:箭头终点的 x,y)。
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np;np.random.seed(5)
plt.rcParams["figure.figsize"] = 4,5
param = {"grid.linewidth" : 1.6,
"grid.color" : "lightgray",
"axes.linewidth" : 1.6,
"axes.edgecolor" : "lightgray"}
plt.rcParams.update(param)
#Data
headh = list("GATCCA")
headv = list("GTGCCT")
v = np.zeros((7,7), dtype=int)
v[1:,1:] = np.random.randint(-2,7, size=(6,6))
arrows = np.random.randint(0,v.shape[1], size=(14,4))
opt = np.array([(0,1),(1,0),(1,1)])
arrows[:,2:] = arrows[:,:2] + opt[np.random.randint(0,3,size=14 )]
arrowsb = np.random.randint(0,v.shape[1], size=(7,4))
optb = np.array([(0,1),(1,0),(1,1)])
arrowsb[:,2:] = arrowsb[:,:2] + optb[np.random.randint(0,3,size=7 )]
#Plot
fig, ax=plt.subplots()
ax.set_xlim(-1.5, v.shape[1]-.5 )
ax.set_ylim(-1.5, v.shape[0]-.5 )
ax.invert_yaxis()
for i in range(v.shape[0]):
for j in range(v.shape[1]):
ax.text(j,i,v[i,j], ha="center", va="center")
for i, l in enumerate(headh):
ax.text(i+1,-1,l, ha="center", va="center", fontweight="semibold")
for i, l in enumerate(headv):
ax.text(-1,i+1,l, ha="center", va="center", fontweight="semibold")
ax.xaxis.set_minor_locator(ticker.FixedLocator(np.arange(-1.5, v.shape[1]-.5,1)))
ax.yaxis.set_minor_locator(ticker.FixedLocator(np.arange(-1.5, v.shape[1]-.5,1)))
plt.tick_params(axis='both', which='both', bottom='off', top='off',
left="off", right="off", labelbottom='off', labelleft='off')
ax.grid(True, which='minor')
arrowprops=dict(facecolor='crimson',alpha=0.5, lw=0,
shrink=0.2,width=2, headwidth=7,headlength=7)
for i in range(arrows.shape[0]):
ax.annotate("", xy=arrows[i,2:], xytext=arrows[i,:2], arrowprops=arrowprops)
arrowprops.update(facecolor='blue')
for i in range(arrowsb.shape[0]):
ax.annotate("", xy=arrowsb[i,2:], xytext=arrowsb[i,:2], arrowprops=arrowprops)
plt.show()
我正在尝试根据 Python 中的全局对齐算法(或 Needleman–Wunsch algorithm)绘制矩阵。
我不知道 matplotlib 是否是这种情况下的最佳工具。我尝试使用 Bokeh 但该结构很难按照我的意愿适合矩阵。
我正在使用 Bio.SeqIO(BioPython 的标准序列 Input/Output 接口)来存储两个序列。
我怎样才能得到类似于这张图片的结果:
在 Matplotlib 中可以吗?我该怎么做?
更新
最后,我能够根据 ImportanceOfBeingErnest 给出的答案构建算法。这是结果:
这里是这个实现的要点:plot_needleman_wunsch.py
这是整个项目(进行中的工作):bmc-sequence-alignment
问题中没有明确说明放置箭头的算法;因此,这个答案侧重于在 matplotlib 中生成类似图的方法。
这里的想法是将数字放在图中的整数位置,并在 n+0.5
处绘制次网格线以获得类似 table 的外观。箭头绘制为 4 列数组中定义的位置之间的注释(前 2 列:箭头起点的 x 和 y,第三和第四列:箭头终点的 x,y)。
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np;np.random.seed(5)
plt.rcParams["figure.figsize"] = 4,5
param = {"grid.linewidth" : 1.6,
"grid.color" : "lightgray",
"axes.linewidth" : 1.6,
"axes.edgecolor" : "lightgray"}
plt.rcParams.update(param)
#Data
headh = list("GATCCA")
headv = list("GTGCCT")
v = np.zeros((7,7), dtype=int)
v[1:,1:] = np.random.randint(-2,7, size=(6,6))
arrows = np.random.randint(0,v.shape[1], size=(14,4))
opt = np.array([(0,1),(1,0),(1,1)])
arrows[:,2:] = arrows[:,:2] + opt[np.random.randint(0,3,size=14 )]
arrowsb = np.random.randint(0,v.shape[1], size=(7,4))
optb = np.array([(0,1),(1,0),(1,1)])
arrowsb[:,2:] = arrowsb[:,:2] + optb[np.random.randint(0,3,size=7 )]
#Plot
fig, ax=plt.subplots()
ax.set_xlim(-1.5, v.shape[1]-.5 )
ax.set_ylim(-1.5, v.shape[0]-.5 )
ax.invert_yaxis()
for i in range(v.shape[0]):
for j in range(v.shape[1]):
ax.text(j,i,v[i,j], ha="center", va="center")
for i, l in enumerate(headh):
ax.text(i+1,-1,l, ha="center", va="center", fontweight="semibold")
for i, l in enumerate(headv):
ax.text(-1,i+1,l, ha="center", va="center", fontweight="semibold")
ax.xaxis.set_minor_locator(ticker.FixedLocator(np.arange(-1.5, v.shape[1]-.5,1)))
ax.yaxis.set_minor_locator(ticker.FixedLocator(np.arange(-1.5, v.shape[1]-.5,1)))
plt.tick_params(axis='both', which='both', bottom='off', top='off',
left="off", right="off", labelbottom='off', labelleft='off')
ax.grid(True, which='minor')
arrowprops=dict(facecolor='crimson',alpha=0.5, lw=0,
shrink=0.2,width=2, headwidth=7,headlength=7)
for i in range(arrows.shape[0]):
ax.annotate("", xy=arrows[i,2:], xytext=arrows[i,:2], arrowprops=arrowprops)
arrowprops.update(facecolor='blue')
for i in range(arrowsb.shape[0]):
ax.annotate("", xy=arrowsb[i,2:], xytext=arrowsb[i,:2], arrowprops=arrowprops)
plt.show()