diff --git a/doc/tutorial.ipynb b/doc/tutorial.ipynb index 8f9e213..b81818f 100644 --- a/doc/tutorial.ipynb +++ b/doc/tutorial.ipynb @@ -29,7 +29,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -38,8 +39,7 @@ "%matplotlib inline\n", "\n", "nt, nx = 100, 30\n", - "da = xr.DataArray(np.random.randn(nt, nx), dims=['time', 'x'],\n", - " name='foo') # all inputs need a name\n", + "da = xr.DataArray(np.random.randn(nt, nx), dims=['time', 'x'])\n", "display(da)\n", "da.plot()" ] @@ -55,16 +55,60 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } + "tags": [] }, "outputs": [], "source": [ "from xhistogram.xarray import histogram\n", "\n", "bins = np.linspace(-4, 4, 20)\n", + "h = histogram(da, bins=[bins])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This error occurred because no name was given to `da` (e.g. `da.name == None`) and `histogram` needs that to determine the name of the output dimension.\n", + "We can solve this by either renaming `da` at the `histogram` input as\n", + "\n", + "```python\n", + "h = histogram(da.rename(\"foo\"), bins=[bins])\n", + "```\n", + "\n", + "or redefining `da` by giving the name at the input" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "da = xr.DataArray(np.random.randn(nt, nx), dims=['time', 'x'], name = \"foo\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can calculate the histogram and visualize it" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, + "tags": [] + }, + "outputs": [], + "source": [ "h = histogram(da, bins=[bins])\n", "display(h)\n", "h.plot()" @@ -90,7 +134,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -113,7 +158,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -136,7 +182,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -158,7 +205,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -182,7 +230,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -219,7 +268,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -232,7 +282,7 @@ " xr.open_dataset(Temp_url).tmn.load(),\n", " xr.open_dataset(Salt_url).smn.load(),\n", " xr.open_dataset(Oxy_url).omn.load()])\n", - "ds" + "display(ds)" ] }, { @@ -249,7 +299,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -264,7 +315,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -292,7 +344,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -301,7 +354,7 @@ "\n", "# Create a dz variable\n", "dz = np.diff(ds.lev)\n", - "dz =np.insert(dz, 0, dz[0])\n", + "dz = np.insert(dz, 0, dz[0])\n", "dz = xr.DataArray(dz, coords= {'lev':ds.lev}, dims='lev')\n", "\n", "# weight by volume of grid cell (resolution = 5degree, 1degree=110km)\n", @@ -319,6 +372,75 @@ "The ridges of this above plot are indicative of T/S classes with a lot of volume, and some of them are indicative of Mode Waters (example Eighteen Degree water with T$\\sim18^oC$, and S$\\sim36.5psu$. " ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's suppose that we have a mask for different regions in the planet. For the sake of simplicity, we will create a mask to separate the globe into three regions.\n", + "\n", + "- Tropical: `np.abs(latitude) <= 30`\n", + "- Temperate: `30 < np.abs(latitude) <= 60`\n", + "- Polar: `60 < np.abs(latitude)`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "zones = np.abs(ds.lat / 30).round().rename(\"zones\")\n", + "display(zones)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now there are two ways of doing that, we can create a new dimension on the histogram" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "zonebins = np.arange(-0.5, 4, 1)\n", + "hTSw = histogram(ds.smn, ds.tmn, zones, bins=[sbins, tbins, zonebins], weights=dVol)\n", + "np.log10(hTSw.T).plot(levels=31, vmin=11.5, vmax=16, cmap='brg', col = \"zones_bin\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or use groupby function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "hTSw = ds.assign(dVol = dVol).groupby(zones).apply(lambda ds: histogram(ds.smn, ds.tmn, bins=[sbins, tbins], weights=ds.dVol))\n", + "np.log10(hTSw.T).plot(levels=31, vmin=11.5, vmax=16, cmap='brg', col = \"zones\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The second option is more verbose, but more efficient and also works with text or mask values that does not vary monotonically." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -339,7 +461,8 @@ "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ @@ -381,9 +504,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "coringa0.3.0", "language": "python", - "name": "python3" + "name": "coringa0.3.0" }, "language_info": { "codemirror_mode": { @@ -395,7 +518,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.9.15" } }, "nbformat": 4,