1
1
"""
2
- ========
3
- Resample
4
- ========
2
+ ===============
3
+ Resampling Data
4
+ ===============
5
5
6
+ Downsampling lowers the sample rate or sample size of a signal. In
7
+ this tutorial, the signal is downsampled when the plot is adjusted
8
+ through dragging and zooming.
6
9
"""
10
+
7
11
import numpy as np
8
12
import matplotlib .pyplot as plt
9
13
@@ -13,18 +17,28 @@ class DataDisplayDownsampler(object):
13
17
def __init__ (self , xdata , ydata ):
14
18
self .origYData = ydata
15
19
self .origXData = xdata
16
- self .ratio = 5
20
+ self .max_points = 50
17
21
self .delta = xdata [- 1 ] - xdata [0 ]
18
22
19
23
def downsample (self , xstart , xend ):
20
- # Very simple downsampling that takes the points within the range
21
- # and picks every Nth point
24
+ # get the points in the view range
22
25
mask = (self .origXData > xstart ) & (self .origXData < xend )
23
- xdata = self .origXData [mask ]
24
- xdata = xdata [::self .ratio ]
26
+ # dilate the mask by one to catch the points just outside
27
+ # of the view range to not truncate the line
28
+ mask = np .convolve ([1 , 1 ], mask , mode = 'same' ).astype (bool )
29
+ # sort out how many points to drop
30
+ ratio = max (np .sum (mask ) // self .max_points , 1 )
25
31
32
+ # mask data
33
+ xdata = self .origXData [mask ]
26
34
ydata = self .origYData [mask ]
27
- ydata = ydata [::self .ratio ]
35
+
36
+ # downsample data
37
+ xdata = xdata [::ratio ]
38
+ ydata = ydata [::ratio ]
39
+
40
+ print ("using {} of {} visible points" .format (
41
+ len (ydata ), np .sum (mask )))
28
42
29
43
return xdata , ydata
30
44
@@ -37,8 +51,9 @@ def update(self, ax):
37
51
self .line .set_data (* self .downsample (xstart , xend ))
38
52
ax .figure .canvas .draw_idle ()
39
53
54
+
40
55
# Create a signal
41
- xdata = np .linspace (16 , 365 , 365 - 16 )
56
+ xdata = np .linspace (16 , 365 , ( 365 - 16 ) * 4 )
42
57
ydata = np .sin (2 * np .pi * xdata / 153 ) + np .cos (2 * np .pi * xdata / 127 )
43
58
44
59
d = DataDisplayDownsampler (xdata , ydata )
@@ -51,5 +66,5 @@ def update(self, ax):
51
66
52
67
# Connect for changing the view limits
53
68
ax .callbacks .connect ('xlim_changed' , d .update )
54
-
69
+ ax . set_xlim ( 16 , 365 )
55
70
plt .show ()
0 commit comments