从绘图屏幕上单击的两点绘制线,然后删除

2024-04-20 03:28:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望这个代码允许我点击绘图屏幕上的两个不同的位置,在每个点击的坐标上画一个“X”,然后在它们之间画一条线。之后,如果我再次单击绘图屏幕,我希望代码删除“X”散点和线条。下面的代码在删除行时遇到问题(用于删除散点)。它不断返回UnboundLocalError:赋值前引用了局部变量“l”。有人能解释一下为什么使用这种方法,remove()方法对散点图有效,而对折线图无效吗?谢谢!你知道吗

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3], [10,20,30])
p_arts = []
px, py = [], []

def onclick(event):
    if len(p_arts) < 2:
        p = ax.scatter(event.xdata, event.ydata)
        p_arts.append(p)
        px.append(event.xdata)
        py.append(event.ydata)
        if len(p_arts) == 2:
            l = ax.plot(px, py)
    else:
        p_arts[0].remove()
        p_arts[1].remove()
        p_arts.clear()
        px.clear()
        py.clear()
        l.remove()
    fig.canvas.draw()

cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()

Tags: 方法代码pyevent绘图屏幕figplt
1条回答
网友
1楼 · 发布于 2024-04-20 03:28:31

首先,让我们看看错误的含义。你知道吗

它在l.remove()行处被提升,表示变量l在函数中的某个地方被定义,但是在调用remove时,它还没有被定义。你知道吗

请注意,l是一个局部变量,这意味着在调用函数时会创建它的一个实例,然后将其销毁;它不会在调用之间传递。你知道吗

很明显,由于l仅在if分支中定义,如果采用else分支,我们将遇到错误,因为对于onclick的特定调用,l不存在。你知道吗

解决方法就是将它附加到p_arts,就像您为scatterplot艺术家所做的那样。我也会稍微整理一下代码,如下所示:

def onclick(event):
    if len(p_arts) == 0:
        # plot first scatter
        scatter_artist = ax.scatter(event.xdata, event.ydata)
        p_arts.append(scatter_artist)

    elif len(p_arts) == 1:
        # plot second scatter and line
        scatter_artist = ax.scatter(event.xdata, event.ydata)
        p_arts.append(scatter_artist)
        line_artist = ax.plot([event.xdata], [event.ydata])[0]
        p_arts.append(line_artist)

    else:
        # remove everything
        for artist in p_arts:
            artist.remove()

    fig.canvas.draw()

相关问题 更多 >