Matplotlib / python 可点击点

问题描述 投票:0回答:3

我有一堆时间序列数据,每 5 秒有一个点。所以,我可以创建一个线图,甚至可以平滑数据以获得更平滑的图。问题是,matplotlib 或 python 中是否有任何方法可以让我点击有效点来做某事?因此,例如,如果该数据存在于我的原始数据中,我将能够单击 (10, 75),然后我将能够在 Python 中执行某些操作。

有什么想法吗?谢谢。

python graph matplotlib plot
3个回答
19
投票

要扩展@tcaswell 所说的内容,请参阅此处的文档:http://matplotlib.org/users/event_handling.html

但是,您可能会发现 pick 事件的快速演示很有用:

import matplotlib.pyplot as plt

def on_pick(event):
    artist = event.artist
    xmouse, ymouse = event.mouseevent.xdata, event.mouseevent.ydata
    x, y = artist.get_xdata(), artist.get_ydata()
    ind = event.ind
    print 'Artist picked:', event.artist
    print '{} vertices picked'.format(len(ind))
    print 'Pick between vertices {} and {}'.format(min(ind), max(ind)+1)
    print 'x, y of mouse: {:.2f},{:.2f}'.format(xmouse, ymouse)
    print 'Data point:', x[ind[0]], y[ind[0]]
    print

fig, ax = plt.subplots()

tolerance = 10 # points
ax.plot(range(10), 'ro-', picker=tolerance)

fig.canvas.callbacks.connect('pick_event', on_pick)

plt.show()

你具体如何处理这个取决于你使用的是什么艺术家(换句话说,你使用的是

ax.plot
还是
ax.scatter
还是
ax.imshow
?)。

Pick 事件将根据所选艺术家具有不同的属性。总会有

event.artist
event.mouseevent
。大多数具有单个元素的艺术家(例如
Line2D
s,
Collections
等)都会有一个列表,其中包含被选为
event.ind
的项目的索引。

如果您想绘制多边形并在其中选择点,请参阅:http://matplotlib.org/examples/event_handling/lasso_demo.html#event-handling-example-code-lasso-demo-py


4
投票

如果你想将额外的属性绑定到你的艺术家对象,例如你正在绘制多部电影的 IMDB 评级,并且你想通过单击它对应的电影的点来查看,你可以通过添加自定义来实现反对你绘制的点,像这样:

import matplotlib.pyplot as plt

class custom_objects_to_plot:
    def __init__(self, x, y, name):
        self.x = x
        self.y = y
        self.name = name

a = custom_objects_to_plot(10, 20, "a")
b = custom_objects_to_plot(30, 5, "b")
c = custom_objects_to_plot(40, 30, "c")
d = custom_objects_to_plot(120, 10, "d")

def on_pick(event):
    print(event.artist.obj.name)

fig, ax = plt.subplots()
for obj in [a, b, c, d]:
    artist = ax.plot(obj.x, obj.y, 'ro', picker=5)[0]
    artist.obj = obj

fig.canvas.callbacks.connect('pick_event', on_pick)

plt.show()

现在当你点击图中的一个点时,相应对象的名称属性将被打印出来。


0
投票

关于问题中的“一堆”,我测试了双轴(否),多轴(是),多图(是)的拾取是否有效:

import numpy as np
from matplotlib.pyplot import subplots

def on_pick(e):
    print(e.artist.s, e.ind)

x = np.linspace(0, np.pi)

fig, ax = subplots(2)
ax[0].plot(x, np.cos(x), picker=5)[0].s = 'cos'
ax[1].plot(x, np.sin(x), picker=5)[0].s = 'sin'
fig.canvas.callbacks.connect('pick_event', on_pick)
fig.tight_layout()
fig.show()

fig, ax0 = subplots()
ax0.plot(x, np.tan(x), picker=5)[0].s = 'tan' # Won't work, masked by ax1.
ax0.set_ylim(-3, 3)
ax1 = ax0.twinx()
ax1.plot(x, np.sqrt(x), picker=5)[0].s = 'sqrt'
fig.canvas.callbacks.connect('pick_event', on_pick)
fig.tight_layout()
fig.show()

示例输出:

cos [6]
sin [32]
sqrt [30]
© www.soinside.com 2019 - 2024. All rights reserved.