2012-02-03 338 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