我正在尝试使用 matplotlib 制作一个交互式绘图,该绘图创建一个端点处带有两个句柄的线段。您可以单击并拖动手柄,线条将刷新以匹配以此方式指定的位置,与此 matplotlib 示例类似多编辑器 http://matplotlib.org/examples/event_handling/poly_editor.html:(如果你看到这个例子,想象一下我想要同样的东西,但只有多边形的一条边)。
我尝试更改 poly_editor 代码以仅使用 Line2D 元素,并且我的程序运行时没有任何错误,只是它根本不在轴上绘制任何内容。我认为这可能是变量范围内的错误,或者与 matplotlib 的绘制调用有关。任何关于错误是什么的指导将不胜感激。
编辑:我进一步进行了一些改进,简化了代码,现在我可以让它绘制线条并打印 epsilon 距离内最近顶点的索引,但线条保持静止并且不会产生动画。更新后的代码如下
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.lines import Line2D
class LineBuilder(object):
epsilon = 0.5
def __init__(self, line):
canvas = line.figure.canvas
self.canvas = canvas
self.line = line
self.axes = line.axes
self.xs = list(line.get_xdata())
self.ys = list(line.get_ydata())
self.ind = None
canvas.mpl_connect('button_press_event', self.button_press_callback)
canvas.mpl_connect('button_release_event', self.button_release_callback)
canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
def get_ind(self, event):
x = np.array(self.line.get_xdata())
y = np.array(self.line.get_ydata())
d = np.sqrt((x-event.xdata)**2 + (y - event.ydata)**2)
if min(d) > self.epsilon:
return None
if d[0] < d[1]:
return 0
else:
return 1
def button_press_callback(self, event):
if event.button != 1:
return
self.ind = self.get_ind(event)
print(self.ind)
self.line.set_animated(True)
self.canvas.draw()
self.background = self.canvas.copy_from_bbox(self.line.axes.bbox)
self.axes.draw_artist(self.line)
self.canvas.blit(self.axes.bbox)
def button_release_callback(self, event):
if event.button != 1:
return
self.ind = None
self.line.set_animated(False)
self.background = None
self.line.figure.canvas.draw()
def motion_notify_callback(self, event):
if event.inaxes != self.line.axes:
return
if event.button != 1:
return
if self.ind is None:
return
self.xs[self.ind] = event.xdata
self.ys[self.ind] = event.ydata
self.line.set_data(self.xs, self.ys)
self.canvas.restore_region(self.background)
self.axes.draw_artist(self.line)
self.canvas.blit(self.axes.bbox)
if __name__ == '__main__':
fig, ax = plt.subplots()
line = Line2D([0,1], [0,1], marker='o', markerfacecolor='red')
ax.add_line(line)
linebuilder = LineBuilder(line)
ax.set_title('click to create lines')
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
plt.show()
预先感谢,凯文。