2012-02-03 176 views
9

我已经用matplotlib成功地绘制了一组日期序列数据(X轴是日期)。但是,我希望能够在绘制的图形上从一个(日期1,y1)到另一个(日期2,y2)手动绘制直线matplotlib交互式图形(手动在图形上绘制线)

我似乎无法找到任何示例说明如何做到这一点 - 或者甚至是可行的。

总之,这就是我想做的事:

  1. 绘制了一组上绘制图形
  2. 保存线的手工画出的线条数据保存到文件
  3. 负载手工画出的线条数据从文件(以重新创建图表)
  4. 理想情况下,我想存储关于画出的线条的元数据'(例如,颜色,线宽等)

有人可以发布一个框架片段(最好有链接到更多信息),以显示如何开始实现此功能(主要要求是能够在图表上手动绘制线条,然后将线条保存/加载到情节)。

注意:通过'手动',我的意思是能够通过点击一个点,然后单击绘图中的另一个点绘制线。绘制在两个点之间的线(或简单地点击的点并拖动,并且在另一点上所绘制的曲线图释放鼠标)

[[更新]]

达维,非常感谢您提供的片段。这使我可以做我正在做的事情 - 但是,只要画布上画线(第二次单击鼠标后),GUI会崩溃,并在控制台上显示此警告消息:

/usr/local/lib/python2.6/dist-packages/matplotlib/backend_bases.py:2192: DeprecationWarning: Using default event loop until function specific to this GUI is implemented 
    warnings.warn(str,DeprecationWarning) 

你知道是什么原因导致此警告和程序突然终止?

另外,是否可以在图上绘制多条线? (我猜这将涉及写一些事件处理程序,将实例化一个linedrawer变量)。目前,我有机会在“应用”突然终止之前画出一行。

+0

“手动”不明确(并且将其用粗体表示并不能解决歧义)。你的意思是手动点击一个点然后点击另一个点,或者你的意思是手动输入内容?或者足够了? – DSM 2012-02-03 23:45:56

+0

@DSM:澄清问题中使用的'手动'的含义。HTH – 2012-02-03 23:53:52

+0

http://matplotlib.sourceforge.net/api/widgets_api.html可能是开始的地方。 – 2012-02-04 00:00:51

回答

9

我会写这样的事:

import matplotlib.pyplot as plt 
class LineDrawer(object): 
    lines = [] 
    def draw_line(self): 
     ax = plt.gca() 
     xy = plt.ginput(2) 

     x = [p[0] for p in xy] 
     y = [p[1] for p in xy] 
     line = plt.plot(x,y) 
     ax.figure.canvas.draw() 

     self.lines.append(line) 

使用ginput()你能避免更复杂的事件处理。它“作品”的方式是你的东西的情节:

plt.plot([1,2,3,4,5]) 
ld = LineDrawer() 
ld.draw_line() # here you click on the plot 

为了节省/行数据加载到一个文件,你可以很容易地实现使用pickleshelve的方法。您也可以通过方法传递必要的元数据draw_line()

+2

+1代码让我在那里(几乎)。这是**完全**我正在尝试做!非常感谢!。目前的代码片段(小命名空间问题除外)存在一些小问题。当我运行脚本时,它允许我通过单击(如我想要的)在画布上绘制 - 但是,在第二次鼠标单击时,绘制线条时,GUI立即崩溃,并且在控制台上有警告消息(请看我更新的问题) – 2012-02-10 10:44:16

+0

确保你在IPython pylab模式下运行这段代码:'ipython -pylab'。这为您正在使用正确的后端设置事件循环,使这个快速和肮脏的交互性工作。 – dawe 2012-02-10 12:16:39