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

python可视化节点关系(三):matplotlib(1)

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

接下来,开始记录使用matplotlib这个号称python使用最广泛的图形库,所遇到的种种神坑。

一、 画节点图:

1. 画节点和箭头

查阅api文档,觉得annotate类封装的不错。

import matplotlib.pyplot as plt
from matplotlib.text import OffsetFrom

bbox_args = dict(boxstyle="round", fc="0.8")
arrow_args = dict(arrowstyle="->")
an1 = plt.annotate('Drag me 1', xy=(.5, .7), xycoords='data',
                   # xytext=(.5, .7), textcoords='data',
                   ha="center", va="center",
                   bbox=bbox_args,
                   # arrowprops=arrow_args
                   )

an2 = plt.annotate('Drag me 2', xy=(.5, .5), xycoords=an1,
                   xytext=(.5, .3), textcoords='axes fraction',
                   va="center", ha="left",
                   bbox=bbox_args,
                   arrowprops=dict(patchB=an1.get_bbox_patch(),
                                   connectionstyle="arc3,rad=0.2",
                                   **arrow_args))
an1.draggable()
an2.draggable()

官方demo不仅实现了两个节点相连,而且可以鼠标拖动,简直完美。


但是问题来了,因为需要画双向箭头,原方法是先画node1,然后画node2+箭头。如果想画node1 指向node2的箭头,由于画node1的时候,node2还未知,因此无法直接画。那么可以在画出node1,node2->node1的时候,再单独画一个箭头使得node1->node2。但是matplotlib的annotate类的坐标系规则,搞得晕头转向。搞了好久,结果都是在其他位置又新加了一个node1,指向了node2。直到...

2. 画双向箭头

直到顿悟,可以先单独画两个节点,然后画两个节点之间的箭头。

# -*- coding: UTF-8 -*-

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

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))

这里的坐标系设置以及arrowprops的设置比较麻烦,搞了好久。主要参数意义参考官方api如下:

patchA, patchB: None, Patch, optional (default: None)
Head and tail patch respectively. matplotlib.patch.Patch instance.

xycoords : str, Artist, Transform, callable or tuple, optional
The coordinate system that xy is given in. The following types of values are supported:

参考:

3. 实现鼠标交互

见下一节

相关文章

网友评论

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

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