<jupyter_start><jupyter_text>Applying a filter to a time-seriesThis example demonstrates low pass filtering a time-series by applying a weighted running mean over the time dimension.The time-series used is the Darwin-only Southern Oscillation index (SOI), which is filtered using two different Lanczos filters, one to filter out time-scales of less than two years and one to filter out time-scales of less than 7 years. References- <NAME>. (1979) Lanczos Filtering in One and Two Dimensions. Journal of Applied Meteorology, Vol 18, pp 1016-1022.- <NAME>. (1984) Signal Versus Noise in the Southern Oscillation. Monthly Weather Review, Vol 112, pp 326-332<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
import iris
import iris.plot as iplt
def low_pass_weights(window, cutoff):
    """Calculate weights for a low pass Lanczos filter."""
    order = ((window - 1) // 2) + 1
    nwts = 2 * order + 1
    w = np.zeros([nwts])
    n = nwts // 2
    w[n] = 2 * cutoff
    k = np.arange(1., n)
    sigma = np.sin(np.pi * k / n) * n / (np.pi * k)
    firstfactor = np.sin(2. * np.pi * cutoff * k) / (np.pi * k)
    w[n-1:0:-1] = firstfactor * sigma
    w[n+1:-1] = firstfactor * sigma
    return w[1:-1]<jupyter_output><empty_output><jupyter_text>Load the monthly-valued Southern Oscillation Index (SOI) time-series.<jupyter_code>fname = iris.sample_data_path('SOI_Darwin.nc')
soi = iris.load_cube(fname)<jupyter_output><empty_output><jupyter_text>The `soi` variable is an Iris cube, and we can look at it directly:<jupyter_code>soi<jupyter_output><empty_output><jupyter_text>Set the filter window length<jupyter_code>window = 121<jupyter_output><empty_output><jupyter_text>Construct 2-year (24-month) and 7-year (84-month) low pass filters for the SOI data which is monthly.<jupyter_code>wgts24 = low_pass_weights(window, 1. / 24.)
wgts84 = low_pass_weights(window, 1. / 84.)<jupyter_output><empty_output><jupyter_text>Apply each filter using the rolling_window method used with the weights keyword argument. A weighted sum is required because the magnitude of the weights are just as important as their relative sizes.`soi24` and `soi84` are also Iris cubes.<jupyter_code>soi24 = soi.rolling_window('time', iris.analysis.SUM, len(wgts24), weights=wgts24)
soi84 = soi.rolling_window('time', iris.analysis.SUM, len(wgts84), weights=wgts84)<jupyter_output><empty_output><jupyter_text>Create some plots of the SOI time series plots and both filtered versions.Note that the Iris plotting routines (`iplt.plot()`) have some extra functionality, compared to the standard Matplotlib Pyplot routines, in that they understand the Iris cube that is the first argument.<jupyter_code>plt.figure(figsize=(9, 4))
iplt.plot(soi, color='0.7', linewidth=1., linestyle='-',
          alpha=1., label='no filter')
iplt.plot(soi24, color='b', linewidth=2., linestyle='-',
          alpha=.7, label='2-year filter')
iplt.plot(soi84, color='r', linewidth=2., linestyle='-',
          alpha=.7, label='7-year filter')
plt.ylim([-4, 4])
plt.title('Southern Oscillation Index (Darwin Only)')
plt.xlabel('Time')
plt.ylabel('SOI')
plt.legend(fontsize=10)
iplt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11890531613715005, 'fraction_numerical': 0.031141868512110725, 'mean_word_length': 4.878003696857671, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '514708', 'license': 'Apache-2.0', 'n_tokens_mistral': 1186, 'n_tokens_neox': 1062, 'n_words': 331, 'path': 'examples/iris/SOI-filtering.ipynb', 'repo_name': 'RETURN-project/eucp', 'size': '3192'}