删除点/线画布 Python Matplotlib

Posted

技术标签:

【中文标题】删除点/线画布 Python Matplotlib【英文标题】:Remove Points / Lines Canvas Python Matplotlib 【发布时间】:2019-09-06 07:31:13 【问题描述】:

我使用以下代码通过鼠标事件在 matplotlib 中绘制线条。每次单击它们都会保存坐标并绘制线条。

from matplotlib import pyplot as plt

class LineBuilder:
def __init__(self, line):
    self.line = line
    self.xs = list(line.get_xdata())
    self.ys = list(line.get_ydata())
    self.cid = line.figure.canvas.mpl_connect('button_press_event', self)
def __call__(self, event):
    if event.inaxes!=self.line.axes: return
    self.xs.append(event.xdata)
    self.ys.append(event.ydata)
    self.line.set_data(self.xs, self.ys)
    self.line.figure.canvas.draw_idle()
    print(self.xs)
    print(self.ys)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('click to build line segments')
line, = ax.plot([0], [0], marker="o", linestyle="") 
linebuilder = LineBuilder(line)
plt.show()

是否可以删除相同的行?例如,如果我的第 2 点不在正确的位置,那么我想删除完整的线和点。

我该怎么做??

【问题讨论】:

【参考方案1】:

由于您要构建的交互比简单地创建用户单击的点更复杂,因此我建议您使用按钮。

您需要准确定义要执行的操作:删除最后一个点、删除所有点、删除除用于初始化的点之外的所有点...

我将根据 Matplotlib 文档中的 this example 向您展示如何创建一个 Reset 按钮来删除所有点。

首先,创建一个您的按钮将填充的Axes 对象。 您需要调整主轴,使两者不重叠。

from matplotlib.widgets import Button

plt.subplots_adjust(bottom=0.2)
breset_ax = plt.axes([0.7, 0.05, 0.1, 0.075])
breset = Button(breset_ax, 'Reset')

然后您将设置按钮的回调。 我发现在 LineBuilder 类中定义该回调很重要,因为它会清除封装的点。

class LineBuilder:
    ...

    def reset(self, _event):
        self.xs = []
        self.ys = []
        self.line.set_data(self.xs, self.ys)
        self.line.figure.canvas.draw_idle()

然后,将该回调绑定到按钮:

breset.on_clicked(linebuilder.reset)

这会给你类似的东西:

点击Reset按钮将删除所有已绘制的点。


完整代码:

from matplotlib import pyplot as plt
from matplotlib.widgets import Button

class LineBuilder:
    def __init__(self, line):
        self.line = line
        self.xs = list(line.get_xdata())
        self.ys = list(line.get_ydata())
        self.cid = line.figure.canvas.mpl_connect('button_press_event', self)

    def __call__(self, event):
        if event.inaxes!=self.line.axes:
            return
        self.xs.append(event.xdata)
        self.ys.append(event.ydata)
        self.line.set_data(self.xs, self.ys)
        self.line.figure.canvas.draw_idle()
        print(self.xs)
        print(self.ys)

    def reset(self, _event):
        self.xs = []
        self.ys = []
        self.line.set_data(self.xs, self.ys)
        self.line.figure.canvas.draw_idle()

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('click to build line segments')
line, = ax.plot([0], [0], marker="o", linestyle="")
linebuilder = LineBuilder(line)

plt.subplots_adjust(bottom=0.2)
breset_ax = plt.axes([0.7, 0.05, 0.1, 0.075])
breset = Button(breset_ax, 'Reset')
breset.on_clicked(linebuilder.reset)

plt.show()

【讨论】:

【参考方案2】:

你能写一个函数来使用 key_press_event 删除一个选择的点吗? 因此,用户将用鼠标选择一个点并使用“删除按钮”删除

类似这样的:

def on_key(event):
    if event.key == u'delete':
        ax = plt.gca()
        if ax.picked_object:
            ax.picked_object.remove()
            ax.picked_object = None
            ax.figure.canvas.draw()

【讨论】:

以上是关于删除点/线画布 Python Matplotlib的主要内容,如果未能解决你的问题,请参考以下文章

如何在 matplotlib 上绘制散点趋势线? Python-熊猫

Python中Matplotlib的点、线形状及颜色

Python基础17 Matplotlib入门使用

『Python』matplotlib划分画布的主要函数

『Python』matplotlib划分画布的主要函数

对于实时数据,Tkinter matplotlib 画布更新太慢