V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
thautwarm
V2EX  ›  Python

"我还想更简单的画点图"

  •  1
     
  •   thautwarm ·
    thautwarm · 2019-04-07 22:07:59 +08:00 · 4874 次点击
    这是一个创建于 2063 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前段时间因为需要画很多很多的点图, 觉得就算用上 graphviz 还是要写很多的重复代码.

    然后我灵机一动, 发现只需要很少的代码就能简化 graphviz 的使用.

    于是就有了这个项目: https://github.com/thautwarm/graphviz-artist

    之前每次画图前都要查文档, 现在就不用了, 如果你有一个支持 mypy 的 Python 自动补全工具(pycharm 等)的话.

    大概的感觉就是

    import graphviz_artist as ga
    # 创建图
    g = ga.Graph(directed=True)
    

    然后点和线的属性都用 attr 子模块来索引,这样你只要输入attr.就能选自己想要的属性.

    g.new就是创建点

    n1 = g.new(attr.Label('hey'), attr.Shape.diamond)
    n2 = g.new(attr.Label('hey'), attr.Shape.hexagon)
    n3 = g.new(attr.Label('you'), attr.Shape.star)
    

    然后可以用>, <, ==来创建点到点之间的线.

    directed = attr.Directed() # 属性, 表示有方向
    
    # `attr.Label` 表示一个在点或者线上显示的文本
    edge_label = attr.Label("passed_here")
    
    
    # `attr.Penwidth` 确定线的粗细
    edge_size = attr.Penwidth(2.)
    
    # `a < b[b_to_c_attrs...] > c`, 其实就是 a <- b, 然后 b -> c, 只是 b->c 的线上有 b_to_c_attrs 这些属性 
    _ = n3[directed, edge_label, edge_size] > n1[directed] == n2 > n3
    
    

    然后显示图

    g.view()
    

    实例图

    个人感觉是简单的代码, 但是用起来有点舒服....

    29 条回复    2019-04-09 10:51:01 +08:00
    scriptB0y
        1
    scriptB0y  
       2019-04-07 23:24:59 +08:00   ❤️ 1
    Cool, 已赞。红姐要不要试试我集成 jupyter 的一个 dot-kernel ?直接写 dot 语言,比写 Python 还省事一些,还能实时渲染出来。https://github.com/laixintao/jupyter-dot-kernel ☺️
    Sparetire
        2
    Sparetire  
       2019-04-07 23:43:29 +08:00 via Android
    是红大大!
    thautwarm
        3
    thautwarm  
    OP
       2019-04-08 00:03:10 +08:00
    @scriptB0y dot-kernel 省事啊。但是你可能不好搞自动补全。。
    thautwarm
        4
    thautwarm  
    OP
       2019-04-08 00:03:44 +08:00
    @Sparetire 啊,您好,我是一个可怜的失足少女
    thautwarm
        5
    thautwarm  
    OP
       2019-04-08 00:06:21 +08:00
    @scriptB0y 嘛,居然是赖兄(逃
    scriptB0y
        6
    scriptB0y  
       2019-04-08 00:09:53 +08:00
    @thautwarm 是啊,自动补全会很难搞,自动缩进我都还没搞定呢 😂 不过 dot 蛮简单的,我用的时候一般都拷贝拷贝 🤪
    zhuangzhuang1988
        7
    zhuangzhuang1988  
       2019-04-08 00:11:11 +08:00
    都不爱 F#了。
    thautwarm
        8
    thautwarm  
    OP
       2019-04-08 00:14:31 +08:00
    @scriptB0y 你这个能不能像 pandas 表格显示那样,把 dot 集成到 python 里啊?我还不会写 notebook extension,有空看一下你的代码。其实我还想着支持 d3 之类的后端,这样以后画点图都可以用 py。
    zwh2698
        9
    zwh2698  
       2019-04-08 00:25:45 +08:00 via Android
    @thautwarm 你是失足少女?我拯救呢,要不要让我拯救?
    secondwtq
        10
    secondwtq  
       2019-04-08 00:35:04 +08:00
    这 operator ... 没事跟 Haskell 学这些没用的歪门邪道
    scriptB0y
        11
    scriptB0y  
       2019-04-08 00:35:28 +08:00
    @thautwarm 没太懂你的意思唉,Graphviz 本身就支持 jupyter 的: https://graphviz.readthedocs.io/en/stable/manual.html#jupyter-notebooks

    我是觉得用 Python 写 dot 太啰嗦了,毕竟 dot 本身是描述图的一个最小的语言,集成到 Python 里面之后要兼顾 Python 的语法来描述图了。d3 如果有 Python 封装的话在 jupyter 里面应该也是可以直接使用的。
    thautwarm
        12
    thautwarm  
    OP
       2019-04-08 00:48:28 +08:00
    @scriptB0y 啊,sorry,我忘了它本身支持 jupyter nb 的事了。

    那等于我们是针对相同问题的不同方案。graphviz 的那个 python 包 API 用起来很 self-repeating,所以我整的是这一个
    EDSL,你就直接写 dot 了。

    直接写 dot 对于会 dot 的人来说就没有学习曲线了,dot 本来也简单,所以挺好的。

    我主要考虑的方面是智能提示,原文也说了嘛,就是忘记写法每次查文档很烦。

    我之前还想用类似办法,搞一个用 python 生成 css 样式的库。但是一来自己没硬性需求,二来工作量大,就没坚持下去。
    thautwarm
        13
    thautwarm  
    OP
       2019-04-08 00:52:39 +08:00
    @secondwtq 咱在世界 FP 领域最权威的教授手下读研,Haskell 是信仰也是必修。你说 Haskell 没用,我听起来就像是你说我削尖脑袋肝这些年是白肝。。。不说了太失败了,让我哭会儿睡了。
    linde
        14
    linde  
       2019-04-08 00:55:49 +08:00   ❤️ 1
    不明觉厉~~,上手了感觉比用工具画图还快!
    secondwtq
        15
    secondwtq  
       2019-04-08 00:56:14 +08:00
    @thautwarm 我应该加个狗头的
    thautwarm
        16
    thautwarm  
    OP
       2019-04-08 00:57:20 +08:00
    @secondwtq 啊,抱歉抱歉。v2 木有表情包看来不只是我一个人难受 www
    thautwarm
        17
    thautwarm  
    OP
       2019-04-08 00:59:50 +08:00
    @linde 有啥不足的就发 issue 呀!到时候加了 d3 才叫舒服。
    看一个 d3 效果? https://github.com/lfkdsk/rbnfrbnf-pretty/
    azh7138m
        18
    azh7138m  
       2019-04-08 01:14:27 +08:00
    如果说简单的话,为啥不用
    https://bramp.github.io/js-sequence-diagrams/
    http://flowchart.js.org/
    这种类型的东西?
    linde
        19
    linde  
       2019-04-08 01:15:58 +08:00
    @thautwarm 这效果真 NB,只能膜拜,不敢提 issue。 哈哈哈哈~~ 给大佬送冰可乐。

    aleung
        20
    aleung  
       2019-04-08 01:20:33 +08:00 via Android   ❤️ 1
    哈哈,搭车推广一下我的工具:用 Excel 表格生成 digraph,也是嫌 dot 繁琐的一个解决方案。
    https://github.com/aleung/depgraph
    thautwarm
        21
    thautwarm  
    OP
       2019-04-08 01:32:07 +08:00 via Android
    @aleung 啊,我说了你不要不开心啊。
    我觉得你这个用起来,要写的和 python 的 graphviz 库差不多,还是有点麻烦的。。11L 赖哥在帖子里有链接。
    我看到你还需要 jdk,这里 js 应该也是有 csv parser 的吧,总觉得这样依赖也有点多😂。
    我这么说,你千万别不开心啊!
    thautwarm
        22
    thautwarm  
    OP
       2019-04-08 01:34:41 +08:00 via Android
    @azh7138m 抽象和目的不一样。但它是一个可行的后端。。谢谢你告知这个,不用下载 graphviz 也能画简洁风格点图的东西!
    baojiweicn2
        23
    baojiweicn2  
       2019-04-08 02:55:54 +08:00 via Android
    我居然想到了多年以前拿到了一坨屎的代码,实在看不出他们的层级关系了,我搞了个 xmind 的 api,画了张类关系图[手动狗头]。
    楼主的这种图,感觉 matplotlib 好像也能画? 不明觉厉。先 star。
    logozy
        24
    logozy  
       2019-04-08 07:03:25 +08:00 via Android
    Star 一个
    thautwarm
        25
    thautwarm  
    OP
       2019-04-08 09:22:30 +08:00 via Android
    @logozy 谢啦
    thautwarm
        26
    thautwarm  
    OP
       2019-04-08 09:26:06 +08:00 via Android
    @baojiweicn2 matplotlib 应该是能作为一个后端的,见 networkx 这个库。但是问题在于自动处理点和线位置这个问题上,graphviz 非常好。而 networkx,点多了会挤成一片。。
    谢谢 star(比心
    uyhyygyug1234
        27
    uyhyygyug1234  
       2019-04-08 09:52:47 +08:00
    @baojiweicn2 同学这个有没有博客介绍一下啊
    baojiwei
        28
    baojiwei  
       2019-04-08 10:18:40 +08:00   ❤️ 1
    @uyhyygyug1234 具体的代码已经找不到了,那时候我还是个小菜鸟的时候,还在写 odoo,这个框架是 orm 学习了 OO 的里面很多特性,很魔,orm 里面有__inherits 的属性,可以把 table 直接 inherit 下来(包括数据以外键的形式 inherits 下来,唉),除此之外,还被各位大佬们写了很魔的写了企业级总线 [居然没有用任何 mq 框架,自己写的] 。(其实就是一坨复杂的一塌糊涂的 [我觉得设计的思想很好的,但是码力有点飘的] ,看着很香的 shi~~)。带我的大佬看我连这个都看不懂 [唉,手动叹气] ,就让我画结构图了。
    结果我画了三天也没画出来。主要是,这些 table 除了可以继承之外,居然还可以多重继承,继承还有依赖,还有原生 many2many。后来耍了个巧,找了个 xmind 的工具画出来了。
    思路基本是:导入 orm 环境,找每个 class 的父类和子类,继承和多重继承关系,外键和约束关系等等。然后调 xmind 的 api 生成图,把关系画出来。然后写 pgsql 的钩子,找到对应的表。
    然后写了半年 odoo,感觉每次洗澡吹头的时间越来越短了。就走了。( MD,他们现在已经 D 轮了)
    走了之后,据说这个脚本用的还不错。主要是每次上线的时候,因为框架自己加的 table 实在太多了,测试找数据都要崩溃了。所以每次都要先跑一次脚本,新生产一个 xmind 和以前的比较一下,才知道这帮幺蛾子开发大佬们又加了哪些表。

    我找了下当初用的轮子应该是这个:[xmind-sdk-python]( https://github.com/xmindltd/xmind-sdk-python)
    不过我发现有这个更好的有意思的项目(已送 star):[xmind2testcase]( https://github.com/zhuifengshen/xmind2testcase)
    大佬可以了解下,感觉用 sqlalchemy 也是可以这么玩的。celery tasks 估计也可以这么玩,他有一个中间件会检查各个 tasks 的依赖,抽出来应该就可以画图了
    python 代码如果 OO 写的好的话,应该也是可以这样玩的。如果 OO 写的不好,估计出来的结果不一定会好。
    uyhyygyug1234
        29
    uyhyygyug1234  
       2019-04-09 10:51:01 +08:00
    @baojiwei 赞!!!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2596 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 11:15 · PVG 19:15 · LAX 03:15 · JFK 06:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.