|
21 | 21 |
|
22 | 22 | _, axes = plt.subplots(nrows=3, figsize=(10, 6 * 3)) |
23 | 23 |
|
24 | | -# Make some data; lots of random noise + small fraction of sine waves |
| 24 | +# Make some data; a 1D random walk + small fraction of sine waves |
25 | 25 | num_series = 10000 |
26 | 26 | num_points = 100 |
27 | | -SNR = 0.05 # Signal to Noise Ratio |
| 27 | +SNR = 0.10 # Signal to Noise Ratio |
28 | 28 | x = np.linspace(0, 4 * np.pi, num_points) |
29 | | -# random noise |
30 | | -Y = np.random.randn(num_series, num_points) |
| 29 | +# random walk |
| 30 | +Y = np.cumsum(np.random.randn(num_series, num_points), axis=-1) |
31 | 31 | # sinusoidal signal |
32 | 32 | num_signal = int(round(SNR * num_series)) |
33 | | -phi = (0.25 * np.pi) * np.random.randn(num_signal, 1) |
34 | | -Y[-num_signal:] = np.sin(x[None, :] - phi) + 0.1 * \ |
35 | | - np.random.randn(num_signal, num_points) |
| 33 | +phi = (np.pi / 8) * np.random.randn(num_signal, 1) # small random offest |
| 34 | +Y[-num_signal:] = (( |
| 35 | + np.sqrt(np.arange(num_points))[None, :] |
| 36 | + * np.sin(x[None, :] - phi)) |
| 37 | + + 0.05 * np.random.randn(num_signal, num_points) |
| 38 | +) |
36 | 39 |
|
37 | 40 | # Plot it using `plot` and the lowest nonzero value of alpha (1/256). |
38 | 41 | # With this view it is extremely difficult to observe the sinusoidal behavior |
|
43 | 46 | axes[0].plot(x, Y[i], color="C0", alpha=1 / 256) |
44 | 47 | toc = time.time() |
45 | 48 | axes[0].set_title( |
46 | | - r"Standard time series visualization using `plt.plot`") |
| 49 | + r"Standard time series visualization using line plot") |
47 | 50 | print(f"{toc-tic:.2f} sec. elapsed") # ~4 seconds |
48 | 51 |
|
49 | 52 |
|
50 | 53 | # Now we will convert the multiple time series into a heat map. Not only will |
51 | 54 | # the hidden signal be more visible, but it is also a much quicker procedure. |
52 | 55 | tic = time.time() |
53 | 56 | # linearly interpolate between the points in each time series |
54 | | -num_fine = 1000 |
| 57 | +num_fine = 400 * 3 |
55 | 58 | x_fine = np.linspace(x.min(), x.max(), num_fine) |
56 | 59 | y_fine = np.zeros((num_series, num_fine)) |
57 | 60 | for i in range(num_series): |
|
62 | 65 |
|
63 | 66 | # Plot (x, y) points in 2d histogram with log colorscale |
64 | 67 | # It is pretty evident that there is some kind of structure under the noise |
65 | | -# that has a periodicity of about ~6 and oscillates between +1/-1. |
66 | | -cmap = copy(plt.cm.Blues) |
| 68 | +cmap = copy(plt.cm.jet) |
67 | 69 | cmap.set_bad(cmap(0)) |
68 | | -h, xedges, yedges = np.histogram2d(x_fine, y_fine, bins=[200, 200]) |
| 70 | +h, xedges, yedges = np.histogram2d(x_fine, y_fine, bins=[400, 100]) |
69 | 71 | axes[1].pcolormesh(xedges, yedges, h.T, cmap=cmap, norm=LogNorm()) |
70 | 72 | axes[1].set_title( |
71 | | - r"Alternative time series vis. using `plt.hist2d` and log color scale") |
| 73 | + r"Alternative time series vis. using 2d histogram and log color scale") |
72 | 74 |
|
73 | | -# It is even visible on a linear color scale |
74 | | -h, xedges, yedges = np.histogram2d(x_fine, y_fine, bins=[200, 200]) |
75 | | -axes[2].pcolormesh(xedges, yedges, h.T, cmap=cmap) |
| 75 | +# Same thing on linear color scale but with different (more visible) cmap |
| 76 | +cmap = copy(plt.cm.Blues) |
| 77 | +cmap.set_bad(cmap(0)) |
| 78 | +h, xedges, yedges = np.histogram2d(x_fine, y_fine, bins=[400, 100]) |
| 79 | +# tune vmax to make signal more visible |
| 80 | +axes[2].pcolormesh(xedges, yedges, h.T, cmap=cmap, vmax=3e3) |
76 | 81 | axes[2].set_title( |
77 | | - r"Alternative time series vis. using `plt.hist2d` and linear color scale") |
| 82 | + r"Alternative time series vis. using 2d histogram and linear color scale") |
78 | 83 | toc = time.time() |
79 | 84 | print(f"{toc-tic:.2f} sec. elapsed") # ~1 sec for both plots + interpolation |
80 | 85 |
|
|
0 commit comments