【问题标题】:Draw lines-points graph绘制线点图
【发布时间】:2014-07-30 17:15:11
【问题描述】:

我有:

  • Q NODES = [(x, y)_1, ........, (x, y)_Q] 的列表,其中每个元素 (x, y) 代表二维笛卡尔空间中节点的空间位置。

  • 一个QxQ矩阵H,其中H[k, l]是连接节点kl的边的长度,如果k和@是H[k, l] == 0 987654329@ 未连接。

  • QxQ 矩阵Z,其中Z[k, l] 是连接节点kl 的边的标量“强度”值。同样,Z[k, l] == 0 如果 kl 未连接。

我想很好地在空间位置绘制节点,通过边缘连接,并使用色标来表示“强度”。

我该怎么做? (我使用 python、sage、matplotlib 和 numpy)

【问题讨论】:

  • 你的图是有向图还是无向图?此外,由于您已经指定了每个节点的(x, y) 位置,H 中的“长度”信息只是多余的,还是需要独立于节点的相对空间位置来表示“长度”?

标签: python numpy matplotlib plot sage


【解决方案1】:

这是一个示例函数,它仅使用 numpy 和 matplotlib 来绘制 无向 图,其中边权重由颜色图表示:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.collections import LineCollection

def plot_undirected_graph(xy, z):

    fig, ax = plt.subplots(1, 1)
    ax.hold(True)

    # the indices of the start, stop nodes for each edge
    i, j = np.where(z)

    # an array of xy values for each line to draw, with dimensions
    # [nedges, start/stop (2), xy (2)]
    segments = np.hstack((xy[i, None, :], xy[j, None, :]))

    # the 'intensity' values for each existing edge
    z_connected = z[i, j]

    # this object will normalize the 'intensity' values into the range [0, 1]
    norm = plt.Normalize(z_connected.min(), z_connected.max())

    # LineCollection wants a sequence of RGBA tuples, one for each line
    colors = plt.cm.jet(norm(z_connected))

    # we can now create a LineCollection from the xy and color values for each
    # line
    lc = LineCollection(segments, colors=colors, linewidths=2,
                        antialiased=True)

    # add the LineCollection to the axes
    ax.add_collection(lc)

    # we'll also plot some markers and numbers for the nodes
    ax.plot(xy[:, 0], xy[:, 1], 'ok', ms=10)
    for ni in xrange(z.shape[0]):
        ax.annotate(str(ni), xy=xy[ni, :], xytext=(5, 5),
                    textcoords='offset points', fontsize='large')

    # to make a color bar, we first create a ScalarMappable, which will map the
    # intensity values to the colormap scale
    sm = plt.cm.ScalarMappable(norm, plt.cm.jet)
    sm.set_array(z_connected)
    cb = plt.colorbar(sm)

    ax.set_xlabel('X position')
    ax.set_ylabel('Y position')
    cb.set_label('Edge intensity')

    return fig, ax

为简单起见,我将NODES 变量的格式更改为(n_nodes, 2) 数组(x, y) 值,尽管您可以使用np.array(NODES) 轻松获得它。我暂时也忽略了H,因为节点之间的欧几里得距离由它们的(x, y) 位置隐含地给出。您始终可以通过其他方式表示H 中的值,例如使用LineCollectionlinewidths

这是一个快速演示:

# some random xy positions:
xy = np.random.rand(10, 2)

# a random adjacency matrix
adj = np.random.poisson(0.2, (10, 10))

# we multiply by this by a matrix of random edge 'intensities'
z = adj * np.random.randn(*adj.shape)

# do the plotting
plot_undirected_graph(xy, z)

输出:

请注意,此示例仅真正适用于无向图。如果Z[k, l]Z[l, k] 都存在,那么在节点lk 之间将绘制两条重叠的线,因此如果两条边的强度值不同,它们将无法通过颜色区分。

有很多专门的 Python 库可用于构建、分析和绘制图形,例如 igraphgraphtoolnetworkx,它们能够很好地绘制有向图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-28
    • 2012-02-02
    • 1970-01-01
    • 2016-03-19
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多