matshow()的替代方法是什么?

4

我有一个 101x101 的矩阵,我想以图形方式进行可视化。到目前为止,我使用了如下的函数matshow来自matplotlib.pyplot

import numpy as np
import random
import matplotlib.pyplot as plt

A = np.zeros((101,101))
# do stuff to randomly change some values of A
plt.ion()
plt.matshow(A,cmap='PuBuGn')
plt.colorbar()
plt.show()

输出结果如下: 在此输入图片描述 你应该将其视为物种之间的交互矩阵,正如你所看到的只有三个物种相互作用强烈。这就是为什么要考虑像我在论文中发现的以下图形一样的可视化方式,但我不知道这是否可以在Python中实现: 在此输入图片描述
1个回答

4

这应该能解决问题:

import numpy as np
import matplotlib.pyplot as plt

def old_graph(A):
    plt.matshow(A,cmap='PuBuGn')
    plt.colorbar()
    plt.title(r"abs$\left(\left[\mathbf{A}_{ij} \right ] \right )$ ; SIS=%d"%(sis,), va='bottom')
    plt.show()

def new_graph(A, sis_list=np.zeros(0,int), symmetric=True, fig=None, pos=111):
    #create and edit figure:
    if fig is None:
        fig = plt.figure()
    ax = fig.add_subplot(pos, projection='polar')
    ax.set_rgrids([1],[' '])
    ax.set_rmax(1)
    ax.set_thetagrids([])
    ax.set_title(r"abs$\left(\left[\mathbf{A}_{ij} \right ] \right )$ ; SIS=%d"%(sis,), va='bottom')
    colormap = plt.get_cmap('PuBuGn')

    # make each species an angle value:
    n_species = A.shape[0]
    angles = np.linspace(0, 2*np.pi, n_species+1)
    # the radius will always be r_max, and each line
    # will always unite two points:
    r = np.ones((2,))
    # prepare list of lines to sort:
    unordered_pairs_and_values = []
    for index_line in xrange(n_species):
        for index_column in xrange(index_line):
            if symmetric:
                value = A[index_line,index_column]
            else: # not symmetric
                value= abs(A[index_line,index_column]- A[index_column,index_line])
            unordered_pairs_and_values.append([[angles[index_line],angles[index_column]], value])
    # sort the lines (otherwise white lines would cover the 'important' ones):
    ordered_pairs_and_values = sorted(unordered_pairs_and_values, key=lambda pair: pair[1])
    # get the maximum value for scaling:
    I_max = ordered_pairs_and_values[-1][1]
    # plot every line in order:
    for pair in ordered_pairs_and_values:
        ax.plot(pair[0], r, color=colormap(pair[1]/I_max), linewidth=2, alpha=0.8)
    # don't know how to add the colorbar:
    #fig.colorbar(orientation='horizontal')
    # mark the angles:
    ax.plot(angles, np.ones(angles.shape), 'ko')
    # mark the important angles (comment if you don't know which ones are these):
    ax.plot(angles[sis_list],  np.ones(sis_list.shape), 'ro')
    fig.show()

if __name__ == '__main__':
    n_species = 51
    sis = 3 # strongly interacting species
    sis_factor = 4.
    A = np.zeros((n_species,n_species))
    # do stuff to randomly change some values of A:
    for index_line in xrange(n_species):
        for index_column in xrange(index_line+1):
            A[index_line,index_column] = np.random.random()
            A[index_column,index_line] = A[index_line,index_column]

    sis_list = np.random.randint(0,n_species,sis)
    for species in sis_list:
        A[species,:] *= sis_factor
        A[:,species] *= sis_factor
        for species2 in sis_list: # correct crossings
            A[species,species2] /= sis_factor
    # stuff to randomly change some values of A done
    old_graph(A=A)
    new_graph(A=A, sis_list=sis_list, symmetric=True)

旧图: old_graph

新图: enter image description here 我仍然不知道:

  • 如何添加颜色条,因为它需要使用了一种颜色映射的绘图。
  • 如何在不改变图形比例的情况下删除极轴刻度(您可以尝试取消注释#ax.set_rticks([]))。

去除互动物种后,图像看起来更好: enter image description here


1
在我忘记之前,我只考虑了矩阵的一半,因为我假设当一种物种与另一种物种相互作用时,这种相互作用在相反方向上是等效的(因此A[i,j]应该等于A[j,i])。否则,我就不知道要使用哪个值来给两种物种之间的线着色。 - berna1111
这已经对我很有帮助了。矩阵 A论文中并不对称,但我想作者们也只考虑了其中一半,否则就没有构建你所正确陈述的图表的方法。 - Zdenko Heyvaert
1
我在Wolfram Alpha找到了这个链接,在Matlab中找到了这个链接,也许它们是你想要的。最后,似乎你的工作与网络有一些相似之处,在SO上找到了这个答案 - berna1111
1
我刚想起来:线的粗细也可以由A[i][j]-A[j][i]定义,这将允许使用整个矩阵并证明使用abs的合理性,因为差值可能是负数。我会在答案中进行编辑。 - berna1111

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接