|
| 1 | +import numpy as np |
| 2 | +import matplotlib.pyplot as plt |
| 3 | +from scikits.audiolab import wavread |
| 4 | + |
| 5 | +# A class that will downsample the data and recompute when zoomed. |
| 6 | +class DataDisplayDownsampler(object): |
| 7 | + def __init__(self, xdata, ydata): |
| 8 | + self.origYData = ydata |
| 9 | + self.origXData = xdata |
| 10 | + self.numpts = 3000 |
| 11 | + self.delta = xdata[-1] - xdata[0] |
| 12 | + |
| 13 | + def resample(self, xstart, xend): |
| 14 | + # Very simple downsampling that takes the points within the range |
| 15 | + # and picks every Nth point |
| 16 | + mask = (self.origXData > xstart) & (self.origXData < xend) |
| 17 | + xdata = self.origXData[mask] |
| 18 | + ratio = int(xdata.size / self.numpts) + 1 |
| 19 | + xdata = xdata[::ratio] |
| 20 | + |
| 21 | + ydata = self.origYData[mask] |
| 22 | + ydata = ydata[::ratio] |
| 23 | + |
| 24 | + return xdata, ydata |
| 25 | + |
| 26 | + def update(self, ax): |
| 27 | + # Update the line |
| 28 | + lims = ax.viewLim |
| 29 | + if np.abs(lims.width - self.delta) > 1e-8: |
| 30 | + self.delta = lims.width |
| 31 | + xstart, xend = lims.intervalx |
| 32 | + self.line.set_data(*self.downsample(xstart, xend)) |
| 33 | + ax.figure.canvas.draw_idle() |
| 34 | + |
| 35 | +# Read data |
| 36 | +data = wavread('/usr/share/sounds/purple/receive.wav')[0] |
| 37 | +ydata = np.tile(data[:, 0], 100) |
| 38 | +xdata = np.arange(ydata.size) |
| 39 | + |
| 40 | +d = DataDisplayDownsampler(xdata, ydata) |
| 41 | + |
| 42 | +fig = plt.figure() |
| 43 | +ax = fig.add_subplot(1, 1, 1) |
| 44 | + |
| 45 | +#Hook up the line |
| 46 | +xdata, ydata = d.downsample(xdata[0], xdata[-1]) |
| 47 | +d.line, = ax.plot(xdata, ydata) |
| 48 | +ax.set_autoscale_on(False) # Otherwise, infinite loop |
| 49 | + |
| 50 | +# Connect for changing the view limits |
| 51 | +ax.callbacks.connect('xlim_changed', d.update) |
| 52 | + |
| 53 | +plt.show() |
0 commit comments