【问题标题】:How can I make an interactive matplotlib legend such that I can remove lines from my plot?如何制作交互式 matplotlib 图例,以便从绘图中删除线条?
【发布时间】:2019-05-08 03:13:37
【问题描述】:

理想情况下,希望通过图例标签旁边的十字来实现这一点,单击这些标签可以从图中删除线条。现在我试图通过单击图例条目的行来从图中删除图形来做到这一点;我通过将图例条目映射到绘图线的字典来做到这一点。我遇到的问题是,只要向图中添加了多条线,我就可以删除除第一条线之外的所有线。我怀疑这个问题可能是由于我重新创建了图例,这可能会弄乱字典映射。

在类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()

【问题讨论】:

  • this example 不是您想要做的事情有多远? (请注意,如果代码不完整,真的很难提供帮助。)
  • @ImportanceOfBeingErnest 而不是切换可见性,我想从图中完全删除一条线(即删除它)。
  • 看起来就像你的代码所做的那样。但是因为它不可运行,所以我不知道它为什么会失败。

标签: python matplotlib plot tkinter


【解决方案1】:

在绘制一条线或删除一条线后,只需清除并将字典映射图例条目重置为图表上的线即可解决问题。我想它以前不起作用,因为图例和图表中对线条的引用不同,除非有人有更好的解决方案,否则我会使用它,因为它没有太多额外的代码。

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

【讨论】:

    猜你喜欢
    • 2012-02-26
    • 1970-01-01
    • 2019-08-22
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2021-01-18
    • 1970-01-01
    相关资源
    最近更新 更多