Python库matplotlib之十二
Python库matplotlib之十二
- 事件处理
- 数据重采样
- 选择事件
事件处理
数据重采样
降级采样会降低信号的采样率或样本大小。通过+和-键,改变横轴的范围,会对信号进行降级采样。
import matplotlib.pyplot as plt
import numpy as npclass DataDisplayDownsampler:def __init__(self, fig, ax, xdata, ydata):self.origYData = ydataself.origXData = xdataself.max_points = 50self.fig = figself.ax = axself.delta = xdata[-1] - xdata[0]self.xlim = [16, 365]ax.set_xlim(*self.xlim)def downsample(self, xstart, xend):mask = (self.origXData > xstart) & (self.origXData < xend) mask = np.convolve([1, 1, 1], mask, mode='same').astype(bool) ratio = max(np.sum(mask) // self.max_points, 1)xdata = self.origXData[mask]ydata = self.origYData[mask]# downsample dataxdata = xdata[::ratio]ydata = ydata[::ratio]return xdata, ydatadef update(self, ax):lims = ax.viewLimif abs(lims.width - self.delta) > 1e-8:self.delta = lims.widthxstart, xend = lims.intervalxm0 = self.downsample(xstart, xend)self.line.set_data(*m0)ax.figure.canvas.draw_idle()def on_press(self, event):if event.key == '+':self.xlim[1] += 10self.ax.set_xlim(*self.xlim)fig.canvas.draw()elif event.key == '-':self.xlim[1] -= 10self.ax.set_xlim(*self.xlim)fig.canvas.draw()if __name__ == "__main__":xdata = np.linspace(16, 365, (365-16)*4)ydata = np.sin(2*np.pi*xdata/153)fig, ax = plt.subplots()d = DataDisplayDownsampler(fig, ax, xdata, ydata)d.line, = ax.plot(xdata, ydata, 'o-')ax.set_autoscale_on(False) # Connect for changing the view limitsax.callbacks.connect('xlim_changed', d.update)fig.canvas.mpl_connect('key_press_event', d.on_press)plt.show()
选择事件
可以通过设置artist的“picker”属性来启用拾取Matplotlib对象,Line2D、Text、Patch、Polygon、AxesImage 等
picker 属性有多种含义:
-
None, 该artist禁用拾取(默认)
-
bool, 如果为 True,则将启用拾取,并且如果鼠标事件位于artist上方,artist将触发拾取事件。设置 pickradius 将添加一个以点为单位的 epsilon 容差,如果其数据在鼠标事件的 epsilon 范围内,artist将触发一个事件。对于某些artist,如线条和补丁集合,artist可以向生成的拾取事件提供附加数据,例如,拾取事件的 epsilon 内的数据索引
-
函数, 如果选择器是可调用的,则它是用户提供的函数,用于确定artist是否被鼠标事件击中。
hit, props = picker(artist, mouseevent)以确定命中测试。如果鼠标事件位于artist上方,则返回 hit=True 并且 props 是要添加到 PickEvent 属性的属性字典。
通过设置“picker”属性启用artist进行拾取后,您需要连接到图形画布 pick_event 以获取鼠标按下事件的拾取回调。例如,
def pick_handler(event):mouseevent = event.mouseeventartist = event.artist# now do something with this...
传递给回调的 pick 事件 (matplotlib.backend_bases.PickEvent) 始终使用两个属性触发:
import matplotlib.pyplot as plt
import numpy as npfrom numpy.random import rand
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
from matplotlib.text import Textlinestyles = ["b-","r-.","g--","r--"]
linestyle_ndx = 0;
rectagles =[]def onpick1(event):global linestyles, linestyle_ndx, figif isinstance(event.artist, Line2D):thisline = event.artistxdata = thisline.get_xdata()ydata = thisline.get_ydata()ind = event.indax1.clear()ax1.plot(xdata, ydata, linestyles[linestyle_ndx], picker=True, pickradius=5)linestyle_ndx += 1if linestyle_ndx >= len(linestyles):linestyle_ndx = 0ax1.set_ylabel('ylabel-'+str(linestyle_ndx), picker=True)ax1.set_title('X: ' + str(xdata[ind]) + " Y: "+ str(ydata[ind]))fig.canvas.draw()elif isinstance(event.artist, Rectangle):patch = event.artistif patch in rectagles:patch.set(facecolor="b", edgecolor="b")rectagles.remove(patch)else: patch.set(facecolor="r", edgecolor="g")rectagles.append(patch)fig.canvas.draw()#print('onpick1 patch:', patch.get_path())elif isinstance(event.artist, Text):text = event.artistif text.get_color() == "r":text.set(color = "#000000")else:text.set(color = "r")fig.canvas.draw()print('onpick1 text:', text.get_text())if __name__ == "__main__":global fig, ax1fig, (ax1, ax2) = plt.subplots(2, 1)ax1.set_title('click on line, rectangles or text', picker=True)ax1.set_ylabel('ylabel', picker=True)x = np.linspace(0, 10 * np.pi, 100)y = np.sin(x)line, = ax1.plot(x, y, picker=True, pickradius=5)# Pick the rectangle.ax2.bar(range(10), rand(10), picker=True, facecolor="b")for label in ax2.get_xticklabels(): # Make the xtick labels pickable.label.set_picker(True)fig.canvas.mpl_connect('pick_event', onpick1)plt.show()