2016-05-21 1 views
0

Я хотел бы кодировать интерактивный генератор кривой Безье, только входы, являющиеся координатами мыши на графике (с matplotlib.pyplot)Python: Клик координаты как можно проще

Таким образом, я бы как узнать, как получить эти координаты и как их складывать в два списка по оси x и по оси Y, используя class и self.functions как можно проще.

Спасибо!

Bipattes

+0

Если вы не хотите изучать основную часть языка, люди не будут очень рады помочь. –

+0

@AlexHall Тогда я хотел бы знать, как кодировать это с помощью классов, но максимально просто: я начинаю понимать, как работают классы. – Bipattes

ответ

1

Там находится в Matplotlib, который возвращает вас координаты мыши при нажатии через участок event. Проверьте следующий рецепт:

import numpy as np 
import matplotlib.pyplot as plt 

class LineBuilder: 
    def __init__(self, line,ax,color): 
     self.line = line 
     self.ax = ax 
     self.color = color 
     self.xs = [] 
     self.ys = [] 
     self.cid = line.figure.canvas.mpl_connect('button_press_event', self) 
     self.counter = 0 
     self.shape_counter = 0 
     self.shape = {} 
     self.precision = 10 

    def __call__(self, event): 
     if event.inaxes!=self.line.axes: return 
     if self.counter == 0: 
      self.xs.append(event.xdata) 
      self.ys.append(event.ydata) 
     if np.abs(event.xdata-self.xs[0])<=self.precision and np.abs(event.ydata-self.ys[0])<=self.precision and self.counter != 0: 
      self.xs.append(self.xs[0]) 
      self.ys.append(self.ys[0]) 
      self.ax.scatter(self.xs,self.ys,s=120,color=self.color) 
      self.ax.scatter(self.xs[0],self.ys[0],s=80,color='blue') 
      self.ax.plot(self.xs,self.ys,color=self.color) 
      self.line.figure.canvas.draw() 
      self.shape[self.shape_counter] = [self.xs,self.ys] 
      self.shape_counter = self.shape_counter + 1 
      self.xs = [] 
      self.ys = [] 
      self.counter = 0 
     else: 
      if self.counter != 0: 
       self.xs.append(event.xdata) 
       self.ys.append(event.ydata) 
      self.ax.scatter(self.xs,self.ys,s=120,color=self.color) 
      self.ax.plot(self.xs,self.ys,color=self.color) 
      self.line.figure.canvas.draw() 
      self.counter = self.counter + 1 

def create_shape_on_image(data,cmap='jet'): 
    def change_shapes(shapes): 
     new_shapes = {} 
     for i in range(len(shapes)): 
      l = len(shapes[i][1]) 
      new_shapes[i] = np.zeros((l,2),dtype='int') 
      for j in range(l): 
       new_shapes[i][j,0] = shapes[i][0][j] 
       new_shapes[i][j,1] = shapes[i][1][j] 
     return new_shapes 
    fig = plt.figure() 
    ax = fig.add_subplot(111) 
    ax.set_title('click to include shape markers (10 pixel precision to close the shape)') 
    line = ax.imshow(data) 
    ax.set_xlim(0,data[:,:,0].shape[1]) 
    ax.set_ylim(0,data[:,:,0].shape[0]) 
    linebuilder = LineBuilder(line,ax,'red') 
    plt.gca().invert_yaxis() 
    plt.show() 
    new_shapes = change_shapes(linebuilder.shape) 
    return new_shapes 

img = np.zeros((100,100,3),dtype='uint') 
shapes = create_shape_on_image(img)[0] 
print(shapes) 

Это немного обширно (вы также можете проверить один из matplotlib примеров), но это позволяет визуально увидеть места, где вы щелкающие (вы можете поместить изображение вместо " черная "матрица для фона). Результат должен быть таким:

mouse click markers in matplotlib plot

Первоначально это было сделано для формы, чтобы быть закрыты, но адаптироваться к вашим потребностям. После закрытия участка, вы будете иметь print для действительных координат:

[[54 13] 
[19 39] 
[19 77] 
[58 78] 
[93 45] 
[90 11] 
[54 13]] 

Если вы хотите, чтобы начать с чем-то более скромным (простым событием нажатия на печать координаты консоли) использовать этот рецепт:

import matplotlib.pyplot as plt 

def onclick(event): 
    print(event.xdata, event.ydata) 

fig,ax = plt.subplots() 
ax.plot(range(10)) 
fig.canvas.mpl_connect('button_press_event', onclick) 
plt.show() 
+0

Хорошо, спасибо, я сделаю так! – Bipattes