python - 如何制作交互式 matplotlib 图例,以便从绘图中删除线条?
问题描述
理想情况下,希望通过图例标签旁边的十字来实现这一点,可以单击以从图中删除线条。现在我试图通过单击图例条目的行来从图中删除图形来做到这一点;我通过字典将图例条目映射到绘图上的行来做到这一点。我遇到的问题是,只要向图中添加了多条线,我就可以删除除第一条线之外的所有线。我怀疑这个问题可能是由于我重新创建了图例,这可能会弄乱字典映射。
像这样在类 init 方法中初始化绘图,
f = Figure(figsize=(1, 1), dpi=100)
self.chart = f.add_subplot(111)
self.lined = dict()
self.canvas = FigureCanvasTkAgg(f, self)
self.canvas.draw()
self.canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
self.canvas.mpl_connect('pick_event', self.remove_graph)
这些是与绘制线条和删除它们有关的功能。
def plot_prices(self, event=None):
ticker = self.entry.get().upper()
with open(suffixed_ticker_dump_path, 'rb') as tickers:
tickers = pickle.load(tickers)
if ticker not in tickers:
self.popupmsg("Invalid ticker input. Enter a valid ticker.")
else:
df = pd.read_csv(os.path.join(daily_data_dir, '{}.csv'.format(ticker)),
index_col=0, parse_dates=True)
prices = df['adjusted_close'].replace(0, np.nan)
line,=self.chart.plot(prices.interpolate(), label=ticker)
self.leg = self.chart.legend(loc='lower right')
legline = self.leg.get_lines()[-1]
legline.set_picker(5)
self.lined[legline] = line
self.canvas.draw()
def remove_graph(self, event=None):
legline = event.artist
origline = self.lined[legline]
origline.remove()
self.leg = self.chart.legend(loc='lower right')
self.canvas.draw()
解决方案
通过在绘制一条线或删除一条线后简单地清除和重置将图例条目映射到图表上的线的字典来解决问题。我想它以前没有工作,因为在图例和图表中对线条的引用不同,除非有人有更好的解决方案,否则我会使用它,因为它没有太多额外的代码。
def plot_prices(self, event=None):
ticker = self.entry.get().upper()
with open(suffixed_ticker_dump_path, 'rb') as tickers:
tickers = pickle.load(tickers)
if ticker not in tickers:
self.popupmsg("Invalid ticker input. Enter a valid ticker.")
else:
df = pd.read_csv(os.path.join(daily_data_dir, '{}.csv'.format(ticker)),
index_col=0, parse_dates=True)
prices = df['adjusted_close'].replace(0, np.nan)
line,=self.chart.plot(prices.interpolate(), label=ticker)
self.leg = self.chart.legend(loc='lower right')
self.reset_line_dict()
self.canvas.draw()
def remove_graph(self, event=None):
legline = event.artist
origline = self.lined[legline]
self.chart.lines.remove(origline)
self.leg = self.chart.legend(loc='lower right')
self.reset_line_dict()
self.canvas.draw()
def reset_line_dict(self):
self.lined.clear()
for legline, origline in zip(self.leg.get_lines(), self.chart.get_lines()):
legline.set_picker(5) # 5 pts tolerance
self.lined[legline] = origline
推荐阅读
- php - 不同 woocommerce 迷你购物车的不同购物车内容
- vue.js - 导入时组件不呈现
- c# - 无法将值传递给其他表单
- apache-spark - 在 Spark-submit --files 中发送的文件的 java.io.FileNotFoundException
- javascript - Episerver - 如何在 CMS 块编辑器中显示/隐藏属性
- node.js - 使用从文件加载的自定义设置扩展配置
- c# - 找不到 System.IO.Compression 程序集
- c++ - UNICODE_STRING 蓝屏死机 WDK
- python - Opencv从视频文件而不是网络摄像头将视频作为output.avi写入
- vba - 如何根据表单上另一个文本框中的日期更改状态 - Access