Matplotlib中使用.remove()删除散点图失效问题求助
解决Matplotlib散点图无法用.remove()删除的问题
问题根源
ax.plot()和ax.scatter()的返回值类型存在差异:
ax.plot()返回Line2D对象的列表(哪怕只绘制一条线,也是长度为1的列表),所以你之前用self.lines[i][0][0]取第一个元素是有效的。ax.scatter()返回单个PathCollection对象,不是列表。当你把它直接加入self.lines后,self.lines[i][0]就是这个PathCollection,再用[0]下标访问自然会报“不可下标”的错误。
另外无需逐个删除散点,PathCollection本身就支持.remove()方法,可一次性移除所有散点。
解决方案
有两种方式可以统一处理折线图和散点图的删除逻辑:
方案1:统一存储格式
添加绘图对象时,不管是plot还是scatter,都将返回值包装成列表,后续删除逻辑无需修改:
# 添加折线图(原写法无需改动,plot本身返回列表) self.lines.append([self.ax.plot(data[x_var], data[y_var], color=widget_color), widget_id, 0]) # 添加散点图,手动将scatter返回值包装为列表 self.lines.append([[self.ax.scatter(data[x_var], data[y_var], color=widget_color)], widget_id, 0])
这样self.lines[i][0]始终是列表,self.lines[i][0][0].remove()就能同时适配Line2D和PathCollection对象。
方案2:修改删除逻辑,适配不同返回类型
如果不想改动存储代码,可在删除时判断对象类型,分别处理:
i = 0 while i < len(self.lines): # 用while循环因为列表会被动态修改 if self.lines[i][1] == widget_id and self.lines[i][2] == axis: plot_item = self.lines[i][0] # 区分plot返回的列表与scatter返回的单个对象 if isinstance(plot_item, list): plot_item[0].remove() else: plot_item.remove() # PathCollection直接调用remove方法 del self.lines[i] else: i += 1
内容的提问来源于stack exchange,提问作者grimad
相关产品推荐
相关产品推荐

