python - 矩阵中单元格之间连接的交互式可视化

标签 python matplotlib traits chaco

我使用 matplotlib 绘制了一个矩阵。我想知道是否有可能使用某些工具包/模块对该图产生一些交互性。

根据我们的分析,我们先验地知道矩阵的哪个单元格与其他单元格相连。我们想要做的是当用户将鼠标指针悬停在矩阵单元格上时,它应该通过(指针或任何其他方式)突出显示它所连接的其他单元格。它是一种图形数据结构,但我希望用户获得交互式体验。

最佳答案

Matplotlib 有一个 event handling API您可以将其用于交互式图形。

下面的示例脚本使用 matshow 绘制了一个矩阵。矩阵的值用颜色编码。

您可以在连接字典中设置您的连接:键是您要为其添加连接的矩阵位置(作为元组),连接在连接点列表中给出(同样作为元组)。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import patches

class MatrixBrowser(object):

    def __init__(self, matrix, matrix_ax, connections):
        self.matrix = matrix
        self.matrix_ax = matrix_ax
        self.con = connections
        self.index = (0, 0)
        self.rect = patches.Rectangle((0, 0), 1.1, 1.1,
                    linewidth=3, fill=False, visible=False)
        self.con_rects = self.add_connection_rects()

    def add_connection_rects(self):
        max_cons = max([len(_) for _ in self.con.values()])
        rects = []
        for con in range(max_cons):
            con_rect = patches.Rectangle((0, 0), 1.1, 1.1, linewidth=5,
                        fill=False, visible=False, edgecolor='red')
            rects.append(con_rect)
            self.matrix_ax.add_patch(con_rect)
        return rects

    def update_connections(self, event):
        current_ax = event.inaxes
        cx = event.xdata
        cy = event.ydata
        # only if the cursor is on the matrix ax
        if current_ax == self.matrix_ax:
            rx = round(abs(cx))
            ry = round(abs(cy))
            if not self.index == (rx, ry):
                # make every previous rect invisible
                for rect in self.con_rects:
                    rect.set_visible(False)
                cons = self.con.get((rx, ry), [])
                for rect, con in zip(self.con_rects, cons):
                    rect.set_xy((con[0] - 0.55, con[1] - 0.55))
                    rect.set_visible(True)
                self.index = (rx, ry)
            self.rect.set_visible(True)
            self.rect.set_xy((rx - 0.55, ry - 0.55))
        else:
            self.rect.set_visible(False)
        plt.draw()

def main(matrix, connections):
    fig, ax = plt.subplots()
    im = ax.matshow(matrix, aspect='auto', cmap=plt.cm.winter)
    plt.colorbar(im, use_gridspec=True)
    browser = MatrixBrowser(matrix, ax, connections)
    ax.add_patch(browser.rect)
    fig.canvas.mpl_connect('motion_notify_event', browser.update_connections)
    plt.tight_layout()
    plt.show()

if __name__ == '__main__':
    matrix = np.random.rand(15, 15) * 10
    connections = {(0, 0): [(1, 1), (2, 2), (10, 2), (8, 5)],
                   (3, 2): [(3, 3)],
                   (14, 14): [(0, 0), (0, 14), (14, 0)]}
    main(matrix, connections)

为了给您留下印象,我添加了一个屏幕截图。黑色矩形随鼠标光标移动,如果当前鼠标位置存在连接,则会出现红色矩形。

在此屏幕截图中,光标位于矩阵中的点 (0, 0) 上。由于为该点定义了一个连接(请参阅连接字典:(0, 0): [(1, 1), (2, 2), (10, 2), (8, 5)]) 定义的连接用红色矩形突出显示。

resulting plot

关于python - 矩阵中单元格之间连接的交互式可视化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10418236/

相关文章:

Python Pylab散点图误差条(每个点的误差都是唯一的)

asynchronous - 如何在 Rust 中返回一个返回特征的函数

scala - 是否可以定义一个未命名的特征并将其用作 Scala 中的混合?

python - 使用带有 IN 语句的 cx_Oracle (Python 3)

python - 当这些列的名称与列表中的名称匹配时,如何跨 pandas 列添加所有值?

python - 你如何在 Peewee 模型中存储列表?

python - matplotlib 条形图 : space out bars

Python 列表理解返回错误标签

python - 动态过度绘制

scala - 特征的多个类型实例中的类型差异