显示 pyplot 图后隐藏线 [英] Hiding lines after showing a pyplot figure

查看:32
本文介绍了显示 pyplot 图后隐藏线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 pyplot 显示最多 30 条线的折线图.我想添加一种方法来快速显示和隐藏图形上的单个线条.Pyplot 确实有一个菜单,您可以在其中编辑线条属性以更改颜色或样式,但是当您想要隐藏线条以隔离您感兴趣的线条时,它相当笨拙.理想情况下,我想在图例上使用复选框显示和隐藏线条.(类似于在像 Paint.Net 这样的图像编辑器中显示和隐藏图层)我不确定这是否可以用 pyplot,所以我对其他模块持开放态度,只要它们有点容易分发.

I'm using pyplot to display a line graph of up to 30 lines. I would like to add a way to quickly show and hide individual lines on the graph. Pyplot does have a menu where you can edit line properties to change the color or style, but its rather clunky when you want to hide lines to isolate the one you're interested in. Ideally, I'd like to use checkboxes on the legend to show and hide lines. (Similar to showing and hiding layers in image editors like Paint.Net) I'm not sure if this is possible with pyplot, so I am open to other modules as long as they're somewhat easy to distribute.

推荐答案

如果您愿意,可以将回调连接到图例,该图例将在单击时显示/隐藏线条.这里有一个简单的例子:http://matplotlib.org/examples/event_handling/legend_picking.html

If you'd like, you can hook up a callback to the legend that will show/hide lines when they're clicked. There's a simple example here: http://matplotlib.org/examples/event_handling/legend_picking.html

这是一个更高级"的例子,它应该不需要手动指定线条和图例标记的关系(还有一些更多的功能).

Here's a "fancier" example that should work without needing to manually specify the relationship of the lines and legend markers (Also has a few more features).

(在 2019 年 8 月更新版本,作为对有关此功能无法正常工作的重复报告的回应;现在应该可以了!对于旧版本,请参阅 版本历史)

import numpy as np
import matplotlib.pyplot as plt


def main():
    x = np.arange(10)
    fig, ax = plt.subplots()
    for i in range(1, 31):
        ax.plot(x, i * x, label=r'$y={}x$'.format(i))

    ax.legend(loc='upper left', bbox_to_anchor=(1.05, 1),
              ncol=2, borderaxespad=0)
    fig.subplots_adjust(right=0.55)
    fig.suptitle('Right-click to hide all\nMiddle-click to show all',
                 va='top', size='large')

    leg = interactive_legend()
    return fig, ax, leg

def interactive_legend(ax=None):
    if ax is None:
        ax = plt.gca()
    if ax.legend_ is None:
        ax.legend()

    return InteractiveLegend(ax.get_legend())

class InteractiveLegend(object):
    def __init__(self, legend):
        self.legend = legend
        self.fig = legend.axes.figure

        self.lookup_artist, self.lookup_handle = self._build_lookups(legend)
        self._setup_connections()

        self.update()

    def _setup_connections(self):
        for artist in self.legend.texts + self.legend.legendHandles:
            artist.set_picker(10) # 10 points tolerance

        self.fig.canvas.mpl_connect('pick_event', self.on_pick)
        self.fig.canvas.mpl_connect('button_press_event', self.on_click)

    def _build_lookups(self, legend):
        labels = [t.get_text() for t in legend.texts]
        handles = legend.legendHandles
        label2handle = dict(zip(labels, handles))
        handle2text = dict(zip(handles, legend.texts))

        lookup_artist = {}
        lookup_handle = {}
        for artist in legend.axes.get_children():
            if artist.get_label() in labels:
                handle = label2handle[artist.get_label()]
                lookup_handle[artist] = handle
                lookup_artist[handle] = artist
                lookup_artist[handle2text[handle]] = artist

        lookup_handle.update(zip(handles, handles))
        lookup_handle.update(zip(legend.texts, handles))

        return lookup_artist, lookup_handle

    def on_pick(self, event):
        handle = event.artist
        if handle in self.lookup_artist:

            artist = self.lookup_artist[handle]
            artist.set_visible(not artist.get_visible())
            self.update()

    def on_click(self, event):
        if event.button == 3:
            visible = False
        elif event.button == 2:
            visible = True
        else:
            return

        for artist in self.lookup_artist.values():
            artist.set_visible(visible)
        self.update()

    def update(self):
        for artist in self.lookup_artist.values():
            handle = self.lookup_handle[artist]
            if artist.get_visible():
                handle.set_visible(True)
            else:
                handle.set_visible(False)
        self.fig.canvas.draw()

    def show(self):
        plt.show()

if __name__ == '__main__':
    fig, ax, leg = main()
    plt.show()

这允许您单击图例项目以打开/关闭其相应的艺术家.例如,你可以从这个:

This allows you to click on legend items to toggle their corresponding artists on/off. For example, you can go from this:

为此:

这篇关于显示 pyplot 图后隐藏线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆