Это не слишком просто, но и не невероятно сложно.В общем, вы бы хотели использовать для этого полноценный графический инструментарий (например, Qt, wx, GTK, TK и т. Д.), Но вы можете сделать это с помощью «чистого» matplotlib.(Matplotlib, конечно, просто использует любой графический интерфейс, который ваша установка настроена для использования за кулисами.)
Ваша первая проблема заключается в том, что вы нигде не храните идентификаторы дорожек.
Это может быть просто:
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 Опять же, более гибко использовать полнофункциональный графический интерфейс, но виджеты 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()