美文网首页
python可视化节点关系(三):matplotlib(2)鼠标

python可视化节点关系(三):matplotlib(2)鼠标

作者: 远行_2a22 | 来源:发表于2019-03-11 21:54 被阅读0次

实现鼠标交互

1. 实现鼠标点击节点高亮

直接上代码:

# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-

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

fig, ax = plt.subplots(figsize=(10,10))
node_pos = [(1, 0), (0, 1), (2,1), (1,2)]
bbox_args = dict(boxstyle="round", fc="0.8")
arrow_args = dict(arrowstyle="->")
an1 = plt.annotate(s="Test 1\n(node1,node2)\n(node3,node4,node5)\n\n\n", xy=node_pos[0], xycoords="data",
                  va="center", ha="center",
                  bbox=dict(boxstyle="round", fc="w", facecolor='green'))


an2 = plt.annotate(s="Test 2\n(node1,node2)", xy=node_pos[1], xycoords="data",
                  va="center", ha="center",
                  bbox=dict(boxstyle="round", fc="w", facecolor='green'))




arrow1 = plt.annotate('', xy=(0, 0), xycoords=an1,
                            xytext=(0, 0), textcoords=an2,  # an1 -> an2
                            size=20, ha="center", va="center",
                            bbox=bbox_args,
                            arrowprops=dict(patchA=an2,
                                            patchB=an1,
                                            connectionstyle="arc3,rad=0.2",
                                            #color='red',
                                            #linewidth=5,
                                            **arrow_args))

arrow2 = plt.annotate('', xy=(0, 0), xycoords=an2,
                            xytext=(0, 0), textcoords=an1,  # an1 -> an2
                            size=20, ha="center", va="center",
                            bbox=bbox_args,

                            arrowprops=dict(patchA=an1,
                                            patchB=an2,
                                            connectionstyle="arc3,rad=0.2",
                                            #color='red',
                                            #linewidth=5,
                                            **arrow_args))

# callback fun
def mouse_click(event):
    if an1.contains(event)[0] == True:  # 获取鼠标事件
        an1.set_bbox(dict(facecolor='red', alpha= 0.5, boxstyle= 'round'))
        fig.canvas.draw()  # 切记要加上这句,否则,回调函数中的参数无法更新

axes = plt.gca()
axes.set_xlim([-2,2])
axes.set_ylim([-2,2])

fig.canvas.mpl_connect('button_press_event', mouse_click)

主要就是实现回调函数onclick。通过点击test1,实现背景高亮。

注意

切记要加上fig.canvas.draw(),否则回调函数中的参数无法更新。这个bug找了好久,都是泪。

2. 实现鼠标悬停在节点,显示节点信息。

# -*- coding: utf-8 -*-

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

fig, ax = plt.subplots(figsize=(10,10))
node_pos = [(1, 0), (0, 1), (2,1), (1,2)]
bbox_args = dict(boxstyle="round", fc="0.8")
arrow_args = dict(arrowstyle="->")
an1 = plt.annotate(s="Test 1\n(node1,node2)\n(node3,node4,node5)\n\n\n", xy=node_pos[0], xycoords="data",
                  va="center", ha="center",
                  bbox=bbox_args)


an2 = plt.annotate(s="Test 2\n(node1,node2)", xy=node_pos[1], xycoords="data",
                  va="center", ha="center",
                  bbox=bbox_args)




arrow1 = plt.annotate('', xy=(0, 0), xycoords=an1,
                            xytext=(0, 0), textcoords=an2,  # an1 -> an2
                            size=20, ha="center", va="center",
                            bbox=bbox_args,
                            arrowprops=dict(patchA=an2,
                                            patchB=an1,
                                            connectionstyle="arc3,rad=0.2",
                                            #color='red',
                                            #linewidth=5,
                                            **arrow_args))

arrow2 = plt.annotate('', xy=(0, 0), xycoords=an2,
                            xytext=(0, 0), textcoords=an1,  # an1 -> an2
                            size=20, ha="center", va="center",
                            bbox=bbox_args,

                            arrowprops=dict(patchA=an1,
                                            patchB=an2,
                                            connectionstyle="arc3,rad=0.2",
                                            #color='red',
                                            #linewidth=5,
                                            **arrow_args))
#fig.canvas.draw()
node_pos = an1.get_position()
tag1 = plt.annotate(s='hello node1', xy=node_pos, xycoords='data',
                     color='red',
                     xytext=(node_pos[0] + 0.3, node_pos[1] + 0.3),
                     textcoords='data', horizontalalignment="left",
                     bbox=bbox_args,
                     annotation_clip=True
                   )
tag1.set_visible(False)

# callback fun
def mouse_click(event):
    if an1.contains(event)[0] == True:  # 获取鼠标事件
        if an1.get_color() != 'red':
            an1.set_color('red')  # set font color
            an1.set_bbox(dict(facecolor='yellow', alpha=1, boxstyle='round'))
        else:
            an1.set_color('black')  # set font color
            an1.set_bbox(bbox_args)
        fig.canvas.draw()  # 切记要加上这句,否则,回调函数中的参数无法更新


# check mouse enter
def mouse_enter(event):
    visible_change_flag = False
    visible_flag = an1.contains(event)[0]  #注意,这里检查节点an1是否包含鼠标,而不是tag1
    if visible_flag != tag1.get_visible():
        visible_change_flag = True
        tag1.set_visible(visible_flag)
    if visible_change_flag:
        fig.canvas.draw()


axes = plt.gca()
axes.set_xlim([-2,2])
axes.set_ylim([-2,2])

fig.canvas.mpl_connect('button_press_event', mouse_click)
fig.canvas.mpl_connect('motion_notify_event', mouse_enter)

效果图


注意

  • 这里检查节点an1是否包含鼠标,而不是tag1
  • 鼠标悬停事件是motion_notify_event,而不是button_press_event

相关文章

网友评论

      本文标题:python可视化节点关系(三):matplotlib(2)鼠标

      本文链接:https://www.haomeiwen.com/subject/ykuipqtx.html