{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualizing 3D Data with Lexcube - Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Preparing the dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can use any 3D data that is gridded and can be loaded with Xarray, e.g. **Zarr** and **NetCDF** files, or Numpy. This includes **local** data sets, **remote** data sets (e.g. via *HTTP* or *S3*) and computed data sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import xarray as xr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ** Option 1: Use a numpy data set\n",
    "# data_source = np.sum(np.mgrid[0:256,0:256,0:256], axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ** Option 2: Load a local xarray data set\n",
    "# data_source = xr.open_dataset(\"/data/my_data_set.zarr\", chunks={}, engine=\"zarr\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# ** Option 3: Load a remote xarray data set\n",
    "ds = xr.open_dataset(\"https://data.rsc4earth.de/download/EarthSystemDataCube/v3.0.2/esdc-8d-0.25deg-256x128x128-3.0.2.zarr/\", chunks={}, engine=\"zarr\")\n",
    "data_source = ds[\"air_temperature_2m\"][256:512,256:512,256:512]\n",
    "data_source"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Visualizing 3D data with Lexcube"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using `lexcube.Cube3DWidget`, you can open an interactive visualization of your 3D data. Use the `cmap` parameter to set a (matplotlib) colormap."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import lexcube"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "w = lexcube.Cube3DWidget(data_source, cmap=\"thermal\")\n",
    "w"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can interact with the cube like this: \n",
    "\n",
    "1. You can zoom (mousewheel) and pan (click and drag) on any side of the cube. \n",
    "2. Clicking and dragging on the black background allows you to change the perspective on the cube.\n",
    "3. Call `w.show_sliders()` and use the sliders for finer selection:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "w.show_sliders()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4. Set `w.xlim`, `w.ylim` or `w.zlim` to change the selection via code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "w.xlim = (140, 250)\n",
    "w.ylim = (85, 200)\n",
    "w.zlim = (0, 140)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Save figure\n",
    "Using `w.savefig`, you can save the currently visible cube as a PNG image. It has three parameters:\n",
    "- fname: the file name of the PNG image. Defaults to `lexcube-{current date and time}.png}\n",
    "- include_ui: whether the axis descriptors and color gradient is included in the exported image.\n",
    "- dpi_scale: higher scale equals higher image quality. Defaults to 2.0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "w.savefig(fname=\"cube.png\", include_ui=True, dpi_scale=3.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Create your own paper data cube"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can generate a template to make your own paper data cube from your currently visible data cube like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "w.save_print_template()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the opened dialog, you can download the print template as either PNG or SVG to your computer. You can also add a custom note to the print template, e.g. to remember specifics about the data set. Printing (recommended: thick paper or photo paper, e.g. 15x20cm), cutting and gluing will give you your own paper data cube for your desk:\n",
    "\n",
    "![Print template graphic](https://raw.githubusercontent.com/msoechting/lexcube/main/readme-media/print-template.png)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. Continue working with the selected data\n",
    "Using `w.get_current_cube_selection()` will return the currently visible 3D sub-selection of your dataset. This allows you to make a selection with Lexcube and continue working with it.\n",
    "\n",
    "Be careful when working with a Jupyter notebook for a longer amount of time, since any change/interaction in the Lexcube widget will change the return value of this function. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "w.get_current_cube_selection()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6. Conclusion\n",
    "\n",
    "Thanks for trying Lexcube! If you have any feature requests or encounter any issues, feel free to [create an issue](https://github.com/msoechting/lexcube/issues/new/choose) or contact me ([@msoechting](https://rsc4earth.de/authors/msoechting)). "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
