Note
Go to the endto download the full example code.
Resampling Data#
Downsampling lowers the sample rate or sample size of a signal. Inthis tutorial, the signal is downsampled when the plot is adjustedthrough dragging and zooming.
Note
This example exercises the interactive capabilities of Matplotlib, and thiswill not appear in the static documentation. Please run this code on yourmachine to see the interactivity.
You can copy and paste individual parts, or download the entire exampleusing the link at the bottom of the page.
importmatplotlib.pyplotaspltimportnumpyasnp# A class that will downsample the data and recompute when zoomed.classDataDisplayDownsampler:def__init__(self,xdata,y1data,y2data):self.origY1Data=y1dataself.origY2Data=y2dataself.origXData=xdataself.max_points=50self.delta=xdata[-1]-xdata[0]defplot(self,ax):x,y1,y2=self._downsample(self.origXData.min(),self.origXData.max())(self.line,)=ax.plot(x,y1,'o-')self.poly_collection=ax.fill_between(x,y1,y2,step="pre",color="r")def_downsample(self,xstart,xend):# get the points in the view rangemask=(self.origXData>xstart)&(self.origXData<xend)# dilate the mask by one to catch the points just outside# of the view range to not truncate the linemask=np.convolve([1,1,1],mask,mode='same').astype(bool)# sort out how many points to dropratio=max(np.sum(mask)//self.max_points,1)# mask dataxdata=self.origXData[mask]y1data=self.origY1Data[mask]y2data=self.origY2Data[mask]# downsample dataxdata=xdata[::ratio]y1data=y1data[::ratio]y2data=y2data[::ratio]print(f"using{len(y1data)} of{np.sum(mask)} visible points")returnxdata,y1data,y2datadefupdate(self,ax):# Update the artistslims=ax.viewLimifabs(lims.width-self.delta)>1e-8:self.delta=lims.widthxstart,xend=lims.intervalxx,y1,y2=self._downsample(xstart,xend)self.line.set_data(x,y1)self.poly_collection.set_data(x,y1,y2,step="pre")ax.figure.canvas.draw_idle()# Create a signalxdata=np.linspace(16,365,(365-16)*4)y1data=np.sin(2*np.pi*xdata/153)+np.cos(2*np.pi*xdata/127)y2data=y1data+.2d=DataDisplayDownsampler(xdata,y1data,y2data)fig,ax=plt.subplots()# Hook up the lined.plot(ax)ax.set_autoscale_on(False)# Otherwise, infinite loop# Connect for changing the view limitsax.callbacks.connect('xlim_changed',d.update)ax.set_xlim(16,365)plt.show()

using 52 of 1396 visible points
Tags:interactivity: zoominteractivity: event-handling