用Python绘制数学图形
我之前问过一个问题,想找一个可以用Python画圆和箭头的工具,有人建议我试试PyQt4。
不过,我的问题是,我找了很多函数,想用来画这些图形,但一直没找到。
所以我想问一下,有没有人知道怎么在PyQt4里画圆、箭头和其他数学符号?请给我指个方向。
顺便说一下,如果你们知道Python里有什么工具可以实现这些功能,请帮帮我。
我需要在我的程序里画非确定性有限自动机(NFA),所以这对我很重要。
http://en.wikipedia.org/wiki/File:NFAexample.svg
非常感谢!
另外,我想补充一下,我不仅仅对PyQt4感兴趣。如果你知道其他可以用Python画数学图形的工具,请帮帮我 :)
3 个回答
使用graphviz,你可以制作像这样的图表:
你可以用这样的代码来实现:
#!/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
来处理这个字符串,传给dot
。dot
可以输出多种格式,包括SVG或PNG。或者,你也可以研究一下pygraphviz,它提供了一个更“Python风格”的接口来使用graphviz库。
另外要注意,graphviz支持UTF-8编码的字符,所以你可以在图表中加入下标和其他数学符号,只需在UTF-8字符集中找到合适的符号即可。
graphviz的一个优点是,你不需要繁琐地指定图表的布局——你只需说明哪些节点是相互连接的。节点的位置基本上是由graphviz自动决定的。
但这个优点也有点缺陷——很难将图表中的元素放置得完全如你所愿。例如,注意到S1和S2并没有水平对齐。我也不知道怎么让从S0指向S1的箭头更优美地弯曲,或者让S1和S2之间的箭头完全对称,或者怎么让从S2指向S1的边标签出现在箭头下方等等……可能有办法做到这些,但我不知道怎么做。
想了解更多graphviz能做的事情,可以查看graphviz画廊。
看看这个API的部分:http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qgraphicsitem.html
我觉得这个类和它的子类可以满足你的需求。对于一些东西,比如箭头,你可能需要用现有的元素,比如线条,来构建它们,或者自己定义一个qgraphicsitem的子类,来实现你想要的功能。