【问题标题】:How to pick a set of lines instead of just a single line?如何选择一组行而不是单行?
【发布时间】:2019-07-25 18:52:46
【问题描述】:

我正在使用 matplolib 的 Line2D 绘制多条线,并且想一次选择或选择所有线。

提供的 MWE 绘制一个三角形(可以是任何多边形或形状),并包含一个可以分别选择每条线的功能。我想通过单击它来选择整个三角形。此外,我注意到如果我添加另一行,onPick 函数根本不起作用。有谁知道我做错了什么?

编辑 正如下面的 cmets 中所建议的,我添加了一个 Polygon 和一个修改后的函数 pick_simple()(来自:https://matplotlib.org/3.1.0/gallery/event_handling/pick_event_demo.html)。但不幸的是,这带来了新的问题。通过绘制多边形,即使我设置了 fill=False 以及线宽和颜色,我也会得到一个填充的蓝色补丁。 pick_simple() 函数也没有做任何让我很困惑的事情。

from matplotlib import pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection


fig = plt.figure()
ax = fig.add_subplot(111)

triangle = [[0.1, 0.3],
            [0.2, 0.8],
            [0.3, 0.5],
            [0.1, 0.3]]

for i in range(len(triangle)-1):
    tri = Line2D([triangle[i][0],triangle[i+1][0]],[triangle[i][1],
            triangle[i+1][1]], linewidth=0.75, color='#F97306')
    tri.set_picker(True)
    ax.add_line(tri)

geometry = [[0.0,0.0],[0.1,0.05],[0.2,0.15],[0.3,0.20],[0.4,0.25],[0.5,0.30],
        [0.6,0.25],[0.7,0.15],[0.8,0.05],[0.9,0.025],[1.0,0.0]]

patches = []
polygon = Polygon(geometry, closed=False, fill=False, linewidth=0.75, color='#F97306')
polygon.set_picker(True)
patches.append(polygon)
p = PatchCollection(patches)
ax.add_collection(p)


plt.show()

def pick_simple():
    def onpick(event):
        if isinstance(event.artist, Polygon):
            patch = event.artist
            print('onpick patch:', patch.get_path())
    fig.canvas.mpl_connect('pick_event', onpick)

def pick_factory(ax):
    def onPick(event):
        if event.inaxes == ax:
            for line in ax.lines:
                if line.get_picker():
                    cont, ind = line.contains(event)
                    if cont:
                        line.set_color('#029386')
                        line.set_linewidth(5)
                        ax.figure.canvas.draw_idle()

    fig = ax.get_figure() # get the figure of interest
    fig.canvas.mpl_connect('button_press_event', onPick)

pick_factory(ax)
pick_simple()

【问题讨论】:

  • 如果要选择一个三角形,请创建 一个 三角形,而不是 3 行。
  • 我编辑了我的问题。这不是关于三角形的。它可以是任何形状。实际上它是翼型的插值,但这对于 mwe 来说已经太多了。
  • 如果你想选择一个多边形,创建 一个 这样的多边形,而不是 N 行。
  • 我创建了一个多边形,并尝试调整一个用于选择多边形艺术家的功能,但不幸的是,一定有很多错误。

标签: python matplotlib picker


【解决方案1】:

有几个小错误。

  • 要选择收藏的成员,您需要将选择器设置为收藏,而不是初始艺术家。因此,pick 回调需要通过event.ind 选择集合的成员。
  • PatchCollection 的目标通常是设置其子项本身的属性,如线宽、颜色等。如果你不想这样,你需要使用match_original=True

完整代码:

from matplotlib import pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection


fig = plt.figure()
ax = fig.add_subplot(111)


geometry = [[0.0,0.0],[0.1,0.05],[0.2,0.15],[0.3,0.20],[0.4,0.25],[0.5,0.30],
        [0.6,0.25],[0.7,0.15],[0.8,0.05],[0.9,0.025],[1.0,0.0]]

patches = []
polygon = Polygon(geometry, closed=False, fill=False, linewidth=3, color='#F97306')
patches.append(polygon)
p = PatchCollection(patches, match_original=True)
p.set_picker(True)
ax.add_collection(p)


def pick_simple():
    def onpick(event):
        if isinstance(event.artist, PatchCollection):
            collection = event.artist
            print('onpick collection:', collection)
            print('picked index', event.ind)
            print('path at index', collection.get_paths()[event.ind[0]])
    return fig.canvas.mpl_connect('pick_event', onpick)


cid = pick_simple()
plt.show()

【讨论】:

  • 这个非常有启发性的答案还有一个问题。如果我想通过使用set_color() 来更改多边形的颜色,我猜我在onpick 的if 语句中添加了这个函数。但我不明白我必须使用哪个对象。例如,collection.set_color()event.ind[0].set_color() 不起作用。
  • 如果改变颜色,需要重新绘制绘图,否则看不到效果。
猜你喜欢
  • 2011-10-10
  • 2015-07-08
  • 2016-11-29
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 2011-09-21
  • 1970-01-01
相关资源
最近更新 更多