【问题标题】:How to display values of an array as colored lattice points?如何将数组的值显示为彩色格点?
【发布时间】:2020-09-16 10:01:23
【问题描述】:

我正在创建一个模拟蛋白质折叠的 Python 程序。我的蛋白质有 19 个元素(氨基酸)长,每个元素由 1 到 20 之间的数字指定。我使用 randint() 创建蛋白质并创建了一个零数组。

蛋白质最初在 21 x 21 阵列中展开并水平居中。所以数组的非零值在第 10 行。我导入了 matplotlib 并使用matshow() 来显示这种排列方式:

.

我喜欢这个图的地方是,很明显蛋白质是由不同的氨基酸/元素组成的,如每个正方形的颜色所示。我想保留这个功能。但是,我希望每个元素都显示为通过链接或网格连接到其邻居的彩色点,而不是正方形:

.

我在下面提供了我的代码。总结一下我的问题:

1) 如何将数组中的元素显示为圆形或格点,并带有连接点的链接?

2) 如何在保持每个元素的颜色相同的情况下执行上述操作?

3) 如何指定零值(当前为紫色)应为白色?我不喜欢其他颜色,我想要白色背景。

import numpy as np
import matplotlib.pyplot as plt
import random
from matplotlib.colors import ListedColormap

###create grid
rows = 21 
columns = 21
x = np.zeros(rows) #create arrays for the x- and y-positions
y = np.zeros(columns)
middle = (rows-1)/2

grid = np.zeros((rows,columns)) #grid = [row][columns] = value = grid[j][i]

###create protein:
n = 20
protein = []
while len(protein) < n:
     a = random.randint(1, 20)
     protein = np.append(protein, a)

###specify initial condition with protein unfolded along y=0
j = int(middle)
i = 1
while i < rows-1:
    grid[j][i] = protein[i]
    i = i+1
print(grid)
plt.matshow(grid)

【问题讨论】:

    标签: python numpy matplotlib


    【解决方案1】:

    可以使用plt.scatter() 绘制彩色圆点。带有plt.plot() 的直线段。

    为了表示折叠,0s、1s 和 -1s 的数组可以表示折叠直行、右转或左转。

    要绘制绘图,请在应用折叠方向的同时创建 xy 位置。这些位置用于绘制线段 (plt.plot) 以及彩色点 (plt.scatter)。要拥有 20 种不同的颜色,可以使用“tab20”colormap

    这里有一些示例代码可以帮助您入门。

    import numpy as np
    from matplotlib import pyplot as plt
    
    n = 20
    protein = np.random.randint(1, 20, n) # n numbers between 1 and 19
    folds = np.zeros(n, dtype=np.int) # default there are no turns
    folds[9] = -1 # turn left after protein 9
    folds[11] = 1 # turn right after protein 11
    folds[15] = -1 # turn left after protein 15
    
    dir = (1, 0)
    pos = (0, 0)
    x = np.zeros_like(protein)
    y = np.zeros_like(protein)
    for i, (p, f) in enumerate(zip(protein, folds)):
        x[i], y[i] = pos
        if f == 1:  # turn right
            dir = (dir[1], -dir[0])
        elif f == -1:  # turn left
            dir = (-dir[1], dir[0])
        pos = (pos[0] + dir[0], pos[1] + dir[1])
    plt.plot(x, y, 'k-', zorder=0)  # straight lines
    # large dots colored via the 'tab20' colormap, set zorder=3 to draw the dots on top of the lines
    plt.scatter(x, y, c=protein, cmap='tab20', s=200, zorder=3) 
    
    plt.axis('off') # don't show the axes
    plt.margins(0.1) # enough margin so that the large scatter dots don't touch the borders
    plt.gca().set_aspect('equal') # equal distances in x and y direction 
    plt.show()
    

    绘制类似于示例“d”的东西:

    n = 15
    protein = np.random.randint(1, 20, n)
    folds = [1, -1, 1, -1, 0, 0, 0, 1, -1, 0, 0, 1, -1, -1, 0]
    

    PS:通过以下改编,显示网格线:

    from matplotlib.ticker import MultipleLocator, NullFormatter
    
    plt.axis('on')
    ax = plt.gca()
    ax.xaxis.set_major_locator(MultipleLocator(1))
    ax.xaxis.set_major_formatter(NullFormatter())
    ax.yaxis.set_major_locator(MultipleLocator(1))
    ax.yaxis.set_major_formatter(NullFormatter())
    ax.tick_params(axis='both', length=0)
    plt.grid(True, ls=':')
    

    【讨论】:

    • 确实如此!这是非常有见地的。非常感谢。
    【解决方案2】:

    第一季度和第二季度- 我认为您希望在当前图表的顶部添加带有不同颜色标记的散点图。添加一条线和不同的颜色标记可能会很棘手,因此您最好的选择可能是简单地添加一个依赖于相同 x/y 值的线图,以便同时更新两者(假设您将它们更新为显示折叠)。给定的代码只是散点图,但它维护了您当前的颜色系统。

    编辑:请参阅其他答案以获得一个很好的例子(散点图和图)。

    import matplotlib.colors as mcolors
    from matplotlib import cm
    normalize = mcolors.Normalize(vmin=0, vmax=20)
    mapping = cm.viridis(normalize(protein))  # maintain current colours
    plt.scatter(range(20), np.broadcast_to(10, 20), c=mapping, marker='o')
    

    Q3- 您可以设置特定颜色图的值以使用 .set_under 显示特定颜色,例如查看此答案-https://stackoverflow.com/a/22552651/9754355 这应该使您的映射背景变为白色。

    cm.viridis.set_under(c='w')
    plt.matshow(grid, vim=1e-9)  # Arbitrary low value.
    

    如果这对您的蛋白质颜色产生负面影响,请考虑使用 numpy NaN 或 infinty 或类似的东西并改为 set_bad。

    【讨论】:

    • 这修复了着色。谢谢!
    猜你喜欢
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 2018-05-21
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    相关资源
    最近更新 更多