.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/1single/plot_eeof_trend.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_1single_plot_eeof_trend.py: Removing nonlinear trends with EEOF analysis ============================================ This tutorial illustrates the application of Extended EOF (EEOF) analysis to isolate and remove nonlinear trends within a dataset. Let's begin by setting up the required packages and fetching the data. .. GENERATED FROM PYTHON SOURCE LINES 10-17 .. code-block:: default import xarray as xr import xeofs as xe import matplotlib.pyplot as plt xr.set_options(display_expand_data=False) .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 18-21 We load the sea surface temperature (SST) data from the xarray tutorial. The dataset consists of monthly averages from 1970 to 2021. To ensure the seasonal cycle doesn't overshadow the analysis, we remove the monthly climatologies. .. GENERATED FROM PYTHON SOURCE LINES 21-26 .. code-block:: default sst = xr.tutorial.open_dataset("ersstv5").sst sst = sst.groupby("time.month") - sst.groupby("time.month").mean("time") .. GENERATED FROM PYTHON SOURCE LINES 27-28 We start by performing a standard EOF analysis on the dataset. .. GENERATED FROM PYTHON SOURCE LINES 28-34 .. code-block:: default eof = xe.models.EOF(n_modes=10) eof.fit(sst, dim="time") scores = eof.scores() components = eof.components() .. GENERATED FROM PYTHON SOURCE LINES 35-39 We immediately see that the first mode represents the global warming trend. Yet, the signal is somewhat muddled by short-term and year-to-year variations. Note the pronounced spikes around 1998 and 2016, hinting at the leakage of ENSO signatures into this mode. .. GENERATED FROM PYTHON SOURCE LINES 39-45 .. code-block:: default fig, ax = plt.subplots(1, 2, figsize=(10, 5)) scores.sel(mode=1).plot(ax=ax[0]) components.sel(mode=1).plot(ax=ax[1]) .. image-sg:: /auto_examples/1single/images/sphx_glr_plot_eeof_trend_001.png :alt: mode = 1, mode = 1 :srcset: /auto_examples/1single/images/sphx_glr_plot_eeof_trend_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 46-51 Now, let's try to identify this trend more cleanly. To this end, we perform an EEOF analysis on the same data with a suitably large embedding dimension. We choose an embedding dimensioncorresponding to 120 months which is large enough to capture long-term trends. To speed up computation, we apply the EEOF analysis to the extended (lag) covariance matrix derived from the first 50 PCs. .. GENERATED FROM PYTHON SOURCE LINES 51-57 .. code-block:: default eeof = xe.models.ExtendedEOF(n_modes=5, tau=1, embedding=120, n_pca_modes=50) eeof.fit(sst, dim="time") components_ext = eeof.components() scores_ext = eeof.scores() .. GENERATED FROM PYTHON SOURCE LINES 58-59 The first mode now represents the global warming trend much more clearly. .. GENERATED FROM PYTHON SOURCE LINES 59-64 .. code-block:: default fig, ax = plt.subplots(1, 2, figsize=(10, 5)) scores_ext.sel(mode=1).plot(ax=ax[0]) components_ext.sel(mode=1, embedding=0).plot(ax=ax[1]) .. image-sg:: /auto_examples/1single/images/sphx_glr_plot_eeof_trend_002.png :alt: mode = 1, embedding = 0, mode = 1 :srcset: /auto_examples/1single/images/sphx_glr_plot_eeof_trend_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 65-66 We can use this to the first mode to remove this nonlinear trend from our original dataset. .. GENERATED FROM PYTHON SOURCE LINES 66-71 .. code-block:: default sst_trends = eeof.inverse_transform(scores_ext.sel(mode=1)) sst_detrended = sst - sst_trends.drop_vars("mode") .. GENERATED FROM PYTHON SOURCE LINES 72-73 Reapplying the standard EOF analysis on our now detrended dataset: .. GENERATED FROM PYTHON SOURCE LINES 73-80 .. code-block:: default eof_model_detrended = xe.models.EOF(n_modes=5) eof_model_detrended.fit(sst_detrended, dim="time") scores_detrended = eof_model_detrended.scores() components_detrended = eof_model_detrended.components() .. GENERATED FROM PYTHON SOURCE LINES 81-82 The first mode now represents ENSO without any trend component. .. GENERATED FROM PYTHON SOURCE LINES 82-88 .. code-block:: default fig, ax = plt.subplots(1, 2, figsize=(10, 5)) scores_detrended.sel(mode=1).plot(ax=ax[0]) components_detrended.sel(mode=1).plot(ax=ax[1]) .. image-sg:: /auto_examples/1single/images/sphx_glr_plot_eeof_trend_003.png :alt: mode = 1, mode = 1 :srcset: /auto_examples/1single/images/sphx_glr_plot_eeof_trend_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 28.072 seconds) .. _sphx_glr_download_auto_examples_1single_plot_eeof_trend.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_eeof_trend.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_eeof_trend.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_