用Python绘制数学图形

0 投票
3 回答
2165 浏览
提问于 2025-04-16 08:12

我之前问过一个问题,想找一个可以用Python画圆和箭头的工具,有人建议我试试PyQt4。

不过,我的问题是,我找了很多函数,想用来画这些图形,但一直没找到。

所以我想问一下,有没有人知道怎么在PyQt4里画圆、箭头和其他数学符号?请给我指个方向。

顺便说一下,如果你们知道Python里有什么工具可以实现这些功能,请帮帮我。

我需要在我的程序里画非确定性有限自动机(NFA),所以这对我很重要。

http://en.wikipedia.org/wiki/File:NFAexample.svg

非常感谢!


另外,我想补充一下,我不仅仅对PyQt4感兴趣。如果你知道其他可以用Python画数学图形的工具,请帮帮我 :)

3 个回答

1

你可以看看 NetworkX。这个工具可能正好符合你的需求!因为你想画非确定性有限自动机(NFA)。在这个 画廊 中,你可以看到一些可以实现的功能。

4

使用graphviz,你可以制作像这样的图表:

alt text

你可以用这样的代码来实现:

#!/usr/bin/env python
# coding: utf-8

import os
import subprocess
import shlex

# dot code based on http://www.graphviz.org/Gallery/directed/fsm.html
dot='''    
digraph finite_state_machine {
        bgcolor="#ffffff"
        rankdir=LR;
        size="8,5"
        node [shape = doublecircle]; S₁ S₃;
        node [shape = circle]; S₀ S₂ S₄;
        node [shape = circle]; S₄; 
        S₀ -> S₁ [ label = ε, weight=-1 ];
        S₀ -> S₃ [ label = ε, weight=-1 ];
        S₁ -> S₂:nw [ label = 0 ];
        S₂ -> S₁:se [ label = 0 ];
        S₁ -> S₁ [ label = 1 ];
        S₂ -> S₂ [ label = 1 ];
        S₃ -> S₄:nw [ label = 1 ];
        S₄ -> S₃:se [ label = 1 ];
        S₃ -> S₃ [ label = 0 ];
        S₄ -> S₄ [ label = 0 ]; 
}
'''
os.chdir('/tmp')
with open('output_dot.svg','w') as outfile:
    subprocess.Popen(shlex.split('dot -Tsvg'),
                     stdin=subprocess.PIPE,stdout=outfile).communicate(dot)

通常,我们是在命令行中调用graphviz的dot程序。它和Python没有直接关系。

不过,如果你想通过编程来制作图表,可以用Python来构建dot代码,把它当作一个大字符串,然后用subprocess.Popen来处理这个字符串,传给dotdot可以输出多种格式,包括SVG或PNG。或者,你也可以研究一下pygraphviz,它提供了一个更“Python风格”的接口来使用graphviz库。

另外要注意,graphviz支持UTF-8编码的字符,所以你可以在图表中加入下标和其他数学符号,只需在UTF-8字符集中找到合适的符号即可。

graphviz的一个优点是,你不需要繁琐地指定图表的布局——你只需说明哪些节点是相互连接的。节点的位置基本上是由graphviz自动决定的。

但这个优点也有点缺陷——很难将图表中的元素放置得完全如你所愿。例如,注意到S1和S2并没有水平对齐。我也不知道怎么让从S0指向S1的箭头更优美地弯曲,或者让S1和S2之间的箭头完全对称,或者怎么让从S2指向S1的边标签出现在箭头下方等等……可能有办法做到这些,但我不知道怎么做。

想了解更多graphviz能做的事情,可以查看graphviz画廊

0

看看这个API的部分:http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qgraphicsitem.html

我觉得这个类和它的子类可以满足你的需求。对于一些东西,比如箭头,你可能需要用现有的元素,比如线条,来构建它们,或者自己定义一个qgraphicsitem的子类,来实现你想要的功能。

撰写回答