2011-08-02 66 views
3

我有一個代碼,用於繪製上方左側圖像中的線條。我想選擇一個區域(上圖中右側顯示一個矩形),並找出該區域內哪些線條對應。將數據限制爲所需的值

代碼繪製在左邊的圖像是:

datfiles = glob.glob("*.dat") 
for asc_filename in datfiles: 
    data = pylab.loadtxt(asc_filename) 
    x, y = data[:,0], data[:,3] 
    pylab.plot(x, y) 

plt.legend() 
pylab.savefig('ts.png') 

哪些模塊,你會建議Python和地方上的代碼,開始什麼想法?

謝謝!

+1

我認爲這個問題是太模糊了那麼在它的當前形式 –

+0

選擇一個區域的...? – BrainStorm

回答

2

這不是太簡單,但也不是難以置信的。一般來說,你需要使用某種完整的gui工具包(例如Qt,wx,GTK,TK等),但是你可以用「純粹」matplotlib來完成。 (當然,Matplotlib只是使用你的安裝配置爲在後臺使用的任何一個gui)。

你的第一個問題是你沒有在任何地方存儲軌道ID。

import pylab 
txt_files = glob.iglob("*.txt") 
for txt_filename in txt_files: 
    data = pylab.loadtxt(txt_filename) 

    t, x, y = data[:,0], data[:,1], data[:,2] 


    line, = pylab.plot(x, y, label=time.ctime(t[0])) 
    line.track_id = filename[:-4] 

你必須將它們存儲在什麼地方,但是:

,因爲它可以很簡單!爲每個matplotlib線藝術家對象添加一個屬性會讓事情變得更容易,但您可以用其他方式輕鬆做到這一點。

對於下一個部分,matplotlib.widgets中有一個小部件可以滿足您的需求。看看這裏的例子:http://matplotlib.sourceforge.net/examples/widgets/rectangle_selector.html同樣,使用成熟的gui工具包更爲靈活,但matplotlib小部件對於這樣的事情可以很好地工作。

最後,您需要了解如何確定您剛繪製的框是否與任何線條重疊。我不會試圖弄清楚頂點之間的一條線段是否穿過框,但是發現一個點是否在它內部很簡單,並且matplotlib已經有很多實用工具可以做到這一點。

全部放在一起變成一個例子:

import matplotlib.pyplot as plt 
import numpy as np 

from matplotlib.widgets import RectangleSelector 
from matplotlib.transforms import Bbox 

def main(): 
    # Generate some random data: 
    data = [] 
    for track_id in xrange(100): 
     a, b = np.random.random(2) 
     x = 100 * a + np.random.random(100).cumsum() 
     y = np.cos(x) + b * np.random.random(100).cumsum() 
     data.append((track_id, x, y)) 

    # Plot it, keeping track of the "track_id" 
    fig, ax = plt.subplots() 
    for track_id, x, y in data: 
     line, = ax.plot(x,y) 
     line.track_id = track_id 

    # Make the selector... 
    selector = RectangleSelector(ax, onselect, drawtype='box') 
    # We could set up a button or keyboard shortcut to activate this, instead... 
    selector.set_active(True) 

    plt.show() 

def onselect(eclick, erelease): 
    """Get the lines in an axis with vertices inside the region selected. 
    "eclick" and "erelease" are matplotlib button_click and button_release 
    events, respectively.""" 
    # Make a matplotlib.transforms.Bbox from the selected region so that we 
    # can more easily deal with finding if points are inside it, etc... 
    left, bottom = min(eclick.x, erelease.x), min(eclick.y, erelease.y) 
    right, top = max(eclick.x, erelease.x), max(eclick.y, erelease.y) 
    region = Bbox.from_extents(left, bottom, right, top) 

    track_ids = [] 
    ax = eclick.inaxes 
    for line in ax.lines: 
     bbox = line.get_window_extent(eclick.canvas) 
     # Start with a rough overlaps... 
     if region.overlaps(bbox): 
      # We need the xy data to be in display coords... 
      xy = ax.transData.transform(line.get_xydata()) 

      # Then make sure that at least one vertex is really inside... 
      if any(region.contains(x,y) for x,y in xy): 
       # Highlight the selected line by making it bold 
       line.set_linewidth(3) 
       track_ids.append(line.track_id) 

    print track_ids 
    eclick.canvas.draw() 

if __name__ == '__main__': 
    main() 

An example of some data being selected

+0

感謝您的回答!歡呼聲 – Chad

+0

Hello Joe;我一直在試圖修改你提供的代碼來暗示我的數據集,但是我失敗了。 – Chad

+0

@Chad - 你還有'selector = RectangleSelector(...)'和'selector.set_active(True)'線嗎?如果沒有,請務必在繪圖之後添加它們。如果是這樣,並且它仍然不起作用,那麼您可能會將錯誤的軸對象傳遞給選擇器。或者使用axis方法(例如'ax.plot(...)'而不是'pylab.plot(...)')或傳入當前軸('RectangleSelector(pylab.gca(),...) ')pylab正在引用。希望有所幫助! –