Repository: AI4S2S/s2spy

Issue:
Return correlation / p_values from RGDR
Currently the correlation and p_values are not accessible by the user. The user can only visualize the those values via RGDR built-in plot functions. The users may need to investigate/store these values in case they want to check the correlation of the precursor fields and target timeseries for all the `i_intervals`. So RGDR should return correlation and p_values.

Discussion:

Patch:
diff --git a/notebooks/tutorial_RGDR.ipynb b/notebooks/tutorial_RGDR.ipynb
index 198ccea..29a7389 100644
--- a/notebooks/tutorial_RGDR.ipynb
+++ b/notebooks/tutorial_RGDR.ipynb
@@ -53,7 +53,7 @@
     "target_timeseries = target_resampled.sel(cluster=3).ts.isel(i_interval=0)\n",
     "precursor_field = field_resampled.sst.isel(i_interval=1)\n",
     "\n",
-    "rgdr = RGDR(target_timeseries, eps_km=600, alpha=0.05, min_area_km2=3000**2)"
+    "rgdr = RGDR(eps_km=600, alpha=0.05, min_area_km2=3000**2)"
    ]
   },
   {
@@ -83,7 +83,7 @@
    ],
    "source": [
     "fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 2))\n",
-    "_ = rgdr.plot_correlation(precursor_field, ax1, ax2)"
+    "_ = rgdr.plot_correlation(precursor_field, target_timeseries, ax1, ax2)"
    ]
   },
   {
@@ -116,20 +116,17 @@
    "source": [
     "fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 2))\n",
     "\n",
-    "_ = rgdr.plot_clusters(precursor_field, ax=ax1)\n",
+    "_ = rgdr.plot_clusters(precursor_field, target_timeseries, ax=ax1)\n",
     "\n",
-    "_ = RGDR(target_timeseries,\n",
-    "         eps_km=600,\n",
-    "         alpha=0.05,\n",
-    "         min_area_km2=1000**2\n",
-    "         ).plot_clusters(precursor_field, ax=ax2)"
+    "_ = RGDR(min_area_km2=1000**2).plot_clusters(precursor_field, target_timeseries, ax=ax2)"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "With `.fit` the RGDR clustering can be fit to a precursor field. This will return the data reduced to clusters:"
+    "With `.fit` the RGDR clustering can be fit to a precursor field.\n",
+    "`.transform` can then be used to return the data reduced to clusters:"
    ]
   },
   {
@@ -171,6 +168,7 @@
        "}\n",
        "\n",
        "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
        "body.vscode-dark {\n",
        "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
        "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
@@ -494,12 +492,14 @@
        "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;sst&#x27; (cluster_labels: 3, anchor_year: 39)&gt;\n",
        "290.8 291.0 290.7 290.1 291.1 291.3 ... 299.0 299.5 298.9 298.9 299.2 298.2\n",
        "Coordinates:\n",
+       "  * anchor_year     (anchor_year) int32 1980 1981 1982 1983 ... 2016 2017 2018\n",
+       "    i_interval      int64 1\n",
        "    index           (anchor_year) int64 1 13 25 37 49 61 ... 409 421 433 445 457\n",
        "    interval        (anchor_year) object (1980-07-02, 1980-08-01] ... (2018-0...\n",
-       "  * anchor_year     (anchor_year) int64 1980 1981 1982 1983 ... 2016 2017 2018\n",
-       "    i_interval      int64 1\n",
        "    target          bool False\n",
-       "  * cluster_labels  (cluster_labels) float64 -2.0 0.0 1.0</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'sst'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>cluster_labels</span>: 3</li><li><span class='xr-has-index'>anchor_year</span>: 39</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-57548d43-1b48-4abf-a765-2fa308c2d9ce' class='xr-array-in' type='checkbox' ><label for='section-57548d43-1b48-4abf-a765-2fa308c2d9ce' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>290.8 291.0 290.7 290.1 291.1 291.3 ... 299.5 298.9 298.9 299.2 298.2</span></div><div class='xr-array-data'><pre>array([[290.79588914, 290.970545  , 290.71731703, 290.0762239 ,\n",
+       "  * cluster_labels  (cluster_labels) int32 -2 0 1\n",
+       "    latitude        (cluster_labels) float64 36.05 nan 29.44\n",
+       "    longitude       (cluster_labels) float64 223.9 nan 185.4</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'sst'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>cluster_labels</span>: 3</li><li><span class='xr-has-index'>anchor_year</span>: 39</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-f5bc8d25-bf34-4c88-9121-f7ab7fd5d804' class='xr-array-in' type='checkbox' ><label for='section-f5bc8d25-bf34-4c88-9121-f7ab7fd5d804' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>290.8 291.0 290.7 290.1 291.1 291.3 ... 299.5 298.9 298.9 299.2 298.2</span></div><div class='xr-array-data'><pre>array([[290.79588914, 290.970545  , 290.71731703, 290.0762239 ,\n",
        "        291.08960917, 291.31511491, 291.11538436, 290.26277142,\n",
        "        290.80443321, 290.99960169, 291.53446464, 291.36075119,\n",
        "        291.85483292, 291.09343404, 291.31408735, 291.41374784,\n",
@@ -528,10 +528,13 @@
        "        298.88763028, 299.2529288 , 299.0168395 , 298.84020348,\n",
        "        298.48441327, 299.30649003, 299.69018872, 299.65241405,\n",
        "        299.320106  , 299.04325189, 299.48610574, 298.91044985,\n",
-       "        298.89195415, 299.19568083, 298.21053747]])</pre></div></div></li><li class='xr-section-item'><input id='section-7b3a0711-0bee-4e8a-bff6-653d382b6cee' class='xr-section-summary-in' type='checkbox'  checked><label for='section-7b3a0711-0bee-4e8a-bff6-653d382b6cee' class='xr-section-summary' >Coordinates: <span>(6)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>index</span></div><div class='xr-var-dims'>(anchor_year)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>1 13 25 37 49 ... 421 433 445 457</div><input id='attrs-67060b83-a064-4867-b21f-60b066184d18' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-67060b83-a064-4867-b21f-60b066184d18' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-2793a313-1fa1-4469-b925-db2c25e8422e' class='xr-var-data-in' type='checkbox'><label for='data-2793a313-1fa1-4469-b925-db2c25e8422e' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([  1,  13,  25,  37,  49,  61,  73,  85,  97, 109, 121, 133, 145,\n",
+       "        298.89195415, 299.19568083, 298.21053747]])</pre></div></div></li><li class='xr-section-item'><input id='section-95b251ac-392b-4d4b-bf6e-b9f7afec9cb5' class='xr-section-summary-in' type='checkbox'  checked><label for='section-95b251ac-392b-4d4b-bf6e-b9f7afec9cb5' class='xr-section-summary' >Coordinates: <span>(8)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>anchor_year</span></div><div class='xr-var-dims'>(anchor_year)</div><div class='xr-var-dtype'>int32</div><div class='xr-var-preview xr-preview'>1980 1981 1982 ... 2016 2017 2018</div><input id='attrs-8dba64f4-e3d0-4ae4-96fa-6a0144a3cfc1' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-8dba64f4-e3d0-4ae4-96fa-6a0144a3cfc1' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-71816fcd-d623-4450-bd28-c276610ad0e4' class='xr-var-data-in' type='checkbox'><label for='data-71816fcd-d623-4450-bd28-c276610ad0e4' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991,\n",
+       "       1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,\n",
+       "       2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,\n",
+       "       2016, 2017, 2018])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>i_interval</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>1</div><input id='attrs-266c79b1-cd75-4fd9-a1a9-6e762b299ed2' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-266c79b1-cd75-4fd9-a1a9-6e762b299ed2' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-808c7c66-0d03-48c8-a094-5c5afae42b3c' class='xr-var-data-in' type='checkbox'><label for='data-808c7c66-0d03-48c8-a094-5c5afae42b3c' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array(1, dtype=int64)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>index</span></div><div class='xr-var-dims'>(anchor_year)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>1 13 25 37 49 ... 421 433 445 457</div><input id='attrs-d96ed652-a251-48e3-a9c9-c78621ce231e' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-d96ed652-a251-48e3-a9c9-c78621ce231e' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-a70f5ba4-8506-474a-81fb-d3e40861c04c' class='xr-var-data-in' type='checkbox'><label for='data-a70f5ba4-8506-474a-81fb-d3e40861c04c' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([  1,  13,  25,  37,  49,  61,  73,  85,  97, 109, 121, 133, 145,\n",
        "       157, 169, 181, 193, 205, 217, 229, 241, 253, 265, 277, 289, 301,\n",
        "       313, 325, 337, 349, 361, 373, 385, 397, 409, 421, 433, 445, 457],\n",
-       "      dtype=int64)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>interval</span></div><div class='xr-var-dims'>(anchor_year)</div><div class='xr-var-dtype'>object</div><div class='xr-var-preview xr-preview'>(1980-07-02, 1980-08-01] ... (20...</div><input id='attrs-51b9c5bf-59b2-45f7-93a9-99744db558c2' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-51b9c5bf-59b2-45f7-93a9-99744db558c2' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-c881e817-cda4-415c-b815-5ad445a749bc' class='xr-var-data-in' type='checkbox'><label for='data-c881e817-cda4-415c-b815-5ad445a749bc' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([Interval(&#x27;1980-07-02&#x27;, &#x27;1980-08-01&#x27;, closed=&#x27;right&#x27;),\n",
+       "      dtype=int64)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>interval</span></div><div class='xr-var-dims'>(anchor_year)</div><div class='xr-var-dtype'>object</div><div class='xr-var-preview xr-preview'>(1980-07-02, 1980-08-01] ... (20...</div><input id='attrs-78c7815f-5b0b-43b4-a8ee-8ba7cbdf6d57' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-78c7815f-5b0b-43b4-a8ee-8ba7cbdf6d57' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-47d98346-f0f3-4b4d-be33-8d9c6f61b92a' class='xr-var-data-in' type='checkbox'><label for='data-47d98346-f0f3-4b4d-be33-8d9c6f61b92a' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([Interval(&#x27;1980-07-02&#x27;, &#x27;1980-08-01&#x27;, closed=&#x27;right&#x27;),\n",
        "       Interval(&#x27;1981-07-02&#x27;, &#x27;1981-08-01&#x27;, closed=&#x27;right&#x27;),\n",
        "       Interval(&#x27;1982-07-02&#x27;, &#x27;1982-08-01&#x27;, closed=&#x27;right&#x27;),\n",
        "       Interval(&#x27;1983-07-02&#x27;, &#x27;1983-08-01&#x27;, closed=&#x27;right&#x27;),\n",
@@ -569,21 +572,20 @@
        "       Interval(&#x27;2015-07-02&#x27;, &#x27;2015-08-01&#x27;, closed=&#x27;right&#x27;),\n",
        "       Interval(&#x27;2016-07-02&#x27;, &#x27;2016-08-01&#x27;, closed=&#x27;right&#x27;),\n",
        "       Interval(&#x27;2017-07-02&#x27;, &#x27;2017-08-01&#x27;, closed=&#x27;right&#x27;),\n",
-       "       Interval(&#x27;2018-07-02&#x27;, &#x27;2018-08-01&#x27;, closed=&#x27;right&#x27;)], dtype=object)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>anchor_year</span></div><div class='xr-var-dims'>(anchor_year)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>1980 1981 1982 ... 2016 2017 2018</div><input id='attrs-28bf1820-f31f-4cd8-8f28-1f70b627f934' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-28bf1820-f31f-4cd8-8f28-1f70b627f934' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-8b53caf6-01e7-48cb-9ba0-3c24fd03fadc' class='xr-var-data-in' type='checkbox'><label for='data-8b53caf6-01e7-48cb-9ba0-3c24fd03fadc' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991,\n",
-       "       1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,\n",
-       "       2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,\n",
-       "       2016, 2017, 2018], dtype=int64)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>i_interval</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>1</div><input id='attrs-927c990d-58a9-42e9-88d9-05a8b451a0e1' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-927c990d-58a9-42e9-88d9-05a8b451a0e1' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-c9cbd978-62e5-4f6b-b471-e0b866de011f' class='xr-var-data-in' type='checkbox'><label for='data-c9cbd978-62e5-4f6b-b471-e0b866de011f' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array(1, dtype=int64)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>target</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>bool</div><div class='xr-var-preview xr-preview'>False</div><input id='attrs-13417705-633c-4a4d-bcca-7aef6bb48cb1' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-13417705-633c-4a4d-bcca-7aef6bb48cb1' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-57435aa5-d3cc-42a2-9fab-c3f1181d81f2' class='xr-var-data-in' type='checkbox'><label for='data-57435aa5-d3cc-42a2-9fab-c3f1181d81f2' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array(False)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>cluster_labels</span></div><div class='xr-var-dims'>(cluster_labels)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-2.0 0.0 1.0</div><input id='attrs-c0794742-d215-4833-a607-f55b9d260507' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-c0794742-d215-4833-a607-f55b9d260507' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-085d4cba-0134-429a-8b20-2f8ee0da0b19' class='xr-var-data-in' type='checkbox'><label for='data-085d4cba-0134-429a-8b20-2f8ee0da0b19' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([-2.,  0.,  1.])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-edc51e75-c5d1-4d3d-acb8-d29e400324e0' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-edc51e75-c5d1-4d3d-acb8-d29e400324e0' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+       "       Interval(&#x27;2018-07-02&#x27;, &#x27;2018-08-01&#x27;, closed=&#x27;right&#x27;)], dtype=object)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>target</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>bool</div><div class='xr-var-preview xr-preview'>False</div><input id='attrs-9c6a8913-5ff1-4399-9a14-1e92e0ecaf40' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-9c6a8913-5ff1-4399-9a14-1e92e0ecaf40' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-f7a6b906-d6f1-4a23-8849-70bd9c64b8bf' class='xr-var-data-in' type='checkbox'><label for='data-f7a6b906-d6f1-4a23-8849-70bd9c64b8bf' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array(False)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>cluster_labels</span></div><div class='xr-var-dims'>(cluster_labels)</div><div class='xr-var-dtype'>int32</div><div class='xr-var-preview xr-preview'>-2 0 1</div><input id='attrs-3666865c-b0b6-4939-8d9f-46eeeef17953' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-3666865c-b0b6-4939-8d9f-46eeeef17953' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-a225f50b-a75d-48fd-972a-b3cdcbadc88a' class='xr-var-data-in' type='checkbox'><label for='data-a225f50b-a75d-48fd-972a-b3cdcbadc88a' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([-2,  0,  1])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>latitude</span></div><div class='xr-var-dims'>(cluster_labels)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>36.05 nan 29.44</div><input id='attrs-83eedce7-6a6b-447b-acf3-da3c8599601d' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-83eedce7-6a6b-447b-acf3-da3c8599601d' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-28d9eff3-8d17-477b-a4c4-3eb11c127cb7' class='xr-var-data-in' type='checkbox'><label for='data-28d9eff3-8d17-477b-a4c4-3eb11c127cb7' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([36.0508552,        nan, 29.4398051])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>longitude</span></div><div class='xr-var-dims'>(cluster_labels)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>223.9 nan 185.4</div><input id='attrs-58fdb13b-0e3c-4e91-a117-8de91280dfb8' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-58fdb13b-0e3c-4e91-a117-8de91280dfb8' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-9729360d-7b98-4363-a1b0-c41a3e1d5a28' class='xr-var-data-in' type='checkbox'><label for='data-9729360d-7b98-4363-a1b0-c41a3e1d5a28' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([223.86658208,          nan, 185.40970765])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-b6f17ab0-1e40-4ee4-a636-991a140d2d05' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-b6f17ab0-1e40-4ee4-a636-991a140d2d05' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
       ],
       "text/plain": [
        "<xarray.DataArray 'sst' (cluster_labels: 3, anchor_year: 39)>\n",
        "290.8 291.0 290.7 290.1 291.1 291.3 ... 299.0 299.5 298.9 298.9 299.2 298.2\n",
        "Coordinates:\n",
+       "  * anchor_year     (anchor_year) int32 1980 1981 1982 1983 ... 2016 2017 2018\n",
+       "    i_interval      int64 1\n",
        "    index           (anchor_year) int64 1 13 25 37 49 61 ... 409 421 433 445 457\n",
        "    interval        (anchor_year) object (1980-07-02, 1980-08-01] ... (2018-0...\n",
-       "  * anchor_year     (anchor_year) int64 1980 1981 1982 1983 ... 2016 2017 2018\n",
-       "    i_interval      int64 1\n",
        "    target          bool False\n",
-       "  * cluster_labels  (cluster_labels) float64 -2.0 0.0 1.0"
+       "  * cluster_labels  (cluster_labels) int32 -2 0 1\n",
+       "    latitude        (cluster_labels) float64 36.05 nan 29.44\n",
+       "    longitude       (cluster_labels) float64 223.9 nan 185.4"
       ]
      },
      "execution_count": 5,
@@ -592,7 +594,8 @@
     }
    ],
    "source": [
-    "clustered_data = rgdr.fit(precursor_field)\n",
+    "rgdr.fit(precursor_field, target_timeseries)\n",
+    "clustered_data = rgdr.transform(precursor_field)\n",
     "xr.set_options(display_expand_data=False) # Hide the full data repr\n",
     "clustered_data"
    ]
@@ -612,7 +615,7 @@
     {
      "data": {
       "text/plain": [
-       "<matplotlib.legend.Legend at 0x2df7dc7b0a0>"
+       "<matplotlib.legend.Legend at 0x1dc9fe35060>"
       ]
      },
      "execution_count": 6,
diff --git a/s2spy/rgdr/rgdr.py b/s2spy/rgdr/rgdr.py
index 35a415f..0e505ca 100644
--- a/s2spy/rgdr/rgdr.py
+++ b/s2spy/rgdr/rgdr.py
@@ -120,7 +120,7 @@ def masked_spherical_dbscan(
     coords = np.radians(coords)
 
     # Prepare labels, default value is 0 (not in cluster)
-    labels = np.zeros(len(coords))
+    labels = np.zeros(len(coords), dtype=int)
 
     for sign, sign_mask in zip([1, -1], [data["corr"] >= 0, data["corr"] < 0]):
         mask = np.logical_and(data["p_val"] < dbscan_params["alpha"], sign_mask)
@@ -224,7 +224,7 @@ class RGDR:
     """Response Guided Dimensionality Reduction."""
 
     def __init__(
-        self, timeseries, eps_km=600, alpha=0.05, min_area_km2=3000**2
+        self, eps_km: float = 600, alpha: float = 0.05, min_area_km2: float = 3000**2
     ) -> None:
         """Response Guided Dimensionality Reduction (RGDR).
 
@@ -240,14 +240,52 @@ class RGDR:
             min_area_km2 (float): The minimum area of a cluster. Clusters smaller than
                 this minimum area will be discarded.
         """
-        self.timeseries = timeseries
         self._clusters = None
         self._area = None
         self._dbscan_params = {"eps": eps_km, "alpha": alpha, "min_area": min_area_km2}
 
+    def get_correlation(
+        self,
+        precursor: xr.DataArray,
+        timeseries: xr.DataArray,
+    ) -> Tuple[xr.DataArray, xr.DataArray]:
+        """Calculates the correlation and p-value between input precursor and timeseries.
+
+        Args:
+            precursor: Precursor field data with the dimensions
+                'latitude', 'longitude', and 'anchor_year'
+            timeseries: Timeseries data with only the dimension 'anchor_year'
+
+        Returns:
+            (correlation, p_value): DataArrays containing the correlation and p-value.
+        """
+        if not isinstance(precursor, xr.DataArray):
+            raise ValueError("Please provide an xr.DataArray, not a dataset")
+
+        return correlation(precursor, timeseries, corr_dim="anchor_year")
+
+    def get_clusters(
+        self,
+        precursor: xr.DataArray,
+        timeseries: xr.DataArray,
+    ) -> xr.DataArray:
+        """Generates clusters for the precursor data.
+
+        Args:
+            precursor: Precursor field data with the dimensions
+                'latitude', 'longitude', and 'anchor_year'
+            timeseries: Timeseries data with only the dimension 'anchor_year'
+
+        Returns:
+            DataArray containing the clusters as masks.
+        """
+        corr, p_val = self.get_correlation(precursor, timeseries)
+        return masked_spherical_dbscan(precursor, corr, p_val, self._dbscan_params)
+
     def plot_correlation(
         self,
         precursor: xr.DataArray,
+        timeseries: xr.DataArray,
         ax1: Optional[plt.Axes] = None,
         ax2: Optional[plt.Axes] = None,
     ) -> List[Type[mpl.collections.QuadMesh]]:
@@ -255,22 +293,19 @@ class RGDR:
         initiated RGDR class and input precursor field.
 
         Args:
-            precursor (xr.DataArray): Precursor field data with the dimensions
+            precursor: Precursor field data with the dimensions
                 'latitude', 'longitude', and 'anchor_year'
-            ax1 (plt.Axes, optional): a matplotlib axis handle to plot
+            timeseries: Timeseries data with only the dimension 'anchor_year'
+            ax1: a matplotlib axis handle to plot
                 the correlation values into. If None, an axis handle will be created
                 instead.
-            ax2 (plt.Axes, optional): a matplotlib axis handle to plot
+            ax2: a matplotlib axis handle to plot
                 the p-values into. If None, an axis handle will be created instead.
 
         Returns:
             List[mpl.collections.QuadMesh]: List of matplotlib artists.
         """
-
-        if not isinstance(precursor, xr.DataArray):
-            raise ValueError("Please provide an xr.DataArray, not a dataset")
-
-        corr, p_val = correlation(precursor, self.timeseries, corr_dim="anchor_year")
+        corr, p_val = self.get_correlation(precursor, timeseries)
 
         if (ax1 is None) and (ax2 is None):
             _, (ax1, ax2) = plt.subplots(ncols=2)
@@ -288,30 +323,32 @@ class RGDR:
         return [plot1, plot2]
 
     def plot_clusters(
-        self, precursor: xr.DataArray, ax: Optional[plt.Axes] = None
+        self,
+        precursor: xr.DataArray,
+        timeseries: xr.DataArray,
+        ax: Optional[plt.Axes] = None,
     ) -> Type[mpl.collections.QuadMesh]:
         """Generates a figure showing the clusters resulting from the initiated RGDR
         class and input precursor field.
 
         Args:
-            precursor: Precursor field data with the dimensions 'latitude', 'longitude',
-                and 'anchor_year'
+            precursor: Precursor field data with the dimensions
+                'latitude', 'longitude', and 'anchor_year'
+            timeseries: Timeseries data with only the dimension 'anchor_year'
             ax (plt.Axes, optional): a matplotlib axis handle to plot the clusters
                 into. If None, an axis handle will be created instead.
 
         Returns:
             matplotlib.collections.QuadMesh: Matplotlib artist.
         """
-        corr, p_val = correlation(precursor, self.timeseries, corr_dim="anchor_year")
-
-        clusters = masked_spherical_dbscan(precursor, corr, p_val, self._dbscan_params)
+        clusters = self.get_clusters(precursor, timeseries)
 
         if ax is None:
             _, ax = plt.subplots()
 
         return clusters.cluster_labels.plot(cmap="viridis", ax=ax)
 
-    def fit(self, precursor: xr.DataArray) -> xr.DataArray:
+    def fit(self, precursor: xr.DataArray, timeseries: xr.DataArray):
         """Fits RGDR clusters to precursor data.
 
         Performs DBSCAN clustering on a prepared DataArray, and then groups the data by
@@ -330,13 +367,15 @@ class RGDR:
         Args:
             precursor: Precursor field data with the dimensions 'latitude', 'longitude',
                 and 'anchor_year'
+            timeseries: Timeseries data with only the dimension 'anchor_year', which
+                will be correlated with the precursor field.
 
         Returns:
             xr.DataArray: The precursor data, with the latitute and longitude dimensions
                 reduced to clusters.
         """
 
-        corr, p_val = correlation(precursor, self.timeseries, corr_dim="anchor_year")
+        corr, p_val = correlation(precursor, timeseries, corr_dim="anchor_year")
 
         masked_data = masked_spherical_dbscan(
             precursor, corr, p_val, self._dbscan_params
@@ -345,12 +384,7 @@ class RGDR:
         self._clusters = masked_data.cluster_labels
         self._area = masked_data.area
 
-        reduced_precursor = utils.weighted_groupby(
-            masked_data, groupby="cluster_labels", weight="area"
-        )
-
-        # Add the geographical centers for later alignment between, e.g., splits
-        return utils.geographical_cluster_center(masked_data, reduced_precursor)
+        return self
 
     def transform(self, data: xr.DataArray) -> xr.DataArray:
         """Apply RGDR on the input data, based on the previous fit.
@@ -366,8 +400,26 @@ class RGDR:
         data["cluster_labels"] = self._clusters
         data["area"] = self._area
 
+        # Add the geographical centers for later alignment between, e.g., splits
         reduced_data = utils.weighted_groupby(
             data, groupby="cluster_labels", weight="area"
         )
 
         return utils.geographical_cluster_center(data, reduced_data)
+
+    def fit_transform(self, precursor: xr.DataArray, timeseries: xr.DataArray):
+        """Fits RGDR clusters to precursor data, and applies RGDR on the input data.
+
+        Args:
+            precursor: Precursor field data with the dimensions 'latitude', 'longitude',
+                and 'anchor_year'
+            timeseries: Timeseries data with only the dimension 'anchor_year', which
+                will be correlated with the precursor field.
+
+        Returns:
+            xr.DataArray: The precursor data, with the latitute and longitude dimensions
+                reduced to clusters.
+        """
+
+        self.fit(precursor, timeseries)
+        return self.transform(precursor)


Test patch:
diff --git a/tests/test_rgdr/test_rgdr.py b/tests/test_rgdr/test_rgdr.py
index a6e9625..3cfb548 100644
--- a/tests/test_rgdr/test_rgdr.py
+++ b/tests/test_rgdr/test_rgdr.py
@@ -167,11 +167,11 @@ class TestRGDR:
     """Test RGDR and its methods."""
 
     @pytest.fixture(autouse=True)
-    def dummy_rgdr(self, example_target):
-        return RGDR(example_target, min_area_km2=1000**2)
+    def dummy_rgdr(self):
+        return RGDR(min_area_km2=1000**2)
 
-    def test_init(self, example_target):
-        rgdr = RGDR(example_target, min_area_km2=1000**2)
+    def test_init(self):
+        rgdr = RGDR(min_area_km2=1000**2)
         assert isinstance(rgdr, RGDR)
 
     def test_transform_before_fit(self, dummy_rgdr, example_field):
@@ -179,27 +179,38 @@ class TestRGDR:
         with pytest.raises(ValueError):
             dummy_rgdr.transform(example_field)
 
-    def test_fit(self, dummy_rgdr, example_field):
-        clustered_data = dummy_rgdr.fit(example_field)
+    def test_fit(self, dummy_rgdr, example_field, example_target):
+        dummy_rgdr.fit(example_field, example_target)
+        assert dummy_rgdr._area is not None
+
+    def test_transform(self, dummy_rgdr, example_field, example_target):
+        dummy_rgdr.fit(example_field, example_target)
+        clustered_data = dummy_rgdr.transform(example_field)
         cluster_labels = np.array([-2.0, -1.0, 0.0, 1.0])
         np.testing.assert_array_equal(clustered_data["cluster_labels"], cluster_labels)
 
-    def test_transform(self, dummy_rgdr, example_field):
-        clustered_data = dummy_rgdr.fit(example_field)
-        clustered_data = dummy_rgdr.transform(example_field)
+    def test_fit_transform_fits(self, example_field, example_target):
+        # Ensures that after fit_transform, the rgdr object is fit.
+        rgdr = RGDR()
+        _ = rgdr.fit_transform(example_field, example_target)
+        assert rgdr._area is not None
+
+    def test_fit_transform(self, example_field, example_target):
+        rgdr = RGDR(min_area_km2=1000**2)
+        clustered_data = rgdr.fit_transform(example_field, example_target)
         cluster_labels = np.array([-2.0, -1.0, 0.0, 1.0])
         np.testing.assert_array_equal(clustered_data["cluster_labels"], cluster_labels)
 
-    def test_corr_plot(self, dummy_rgdr, example_field):
-        dummy_rgdr.plot_correlation(example_field)
+    def test_corr_plot(self, dummy_rgdr, example_field, example_target):
+        dummy_rgdr.plot_correlation(example_field, example_target)
 
-    def test_corr_plot_ax(self, dummy_rgdr, example_field):
+    def test_corr_plot_ax(self, dummy_rgdr, example_field, example_target):
         _, (ax1, ax2) = plt.subplots(ncols=2)
-        dummy_rgdr.plot_correlation(example_field, ax1=ax1, ax2=ax2)
+        dummy_rgdr.plot_correlation(example_field, example_target, ax1=ax1, ax2=ax2)
 
-    def test_cluster_plot(self, dummy_rgdr, example_field):
-        dummy_rgdr.plot_clusters(example_field)
+    def test_cluster_plot(self, dummy_rgdr, example_field, example_target):
+        dummy_rgdr.plot_clusters(example_field, example_target)
 
-    def test_cluster_plot_ax(self, dummy_rgdr, example_field):
+    def test_cluster_plot_ax(self, dummy_rgdr, example_field, example_target):
         _, ax = plt.subplots()
-        dummy_rgdr.plot_clusters(example_field, ax=ax)
+        dummy_rgdr.plot_clusters(example_field, example_target, ax=ax)