From 8d28d09fa301d50dc7b60fdd7e9ee4c4c0914d3d Mon Sep 17 00:00:00 2001 From: Qiusheng Wu Date: Sat, 7 Oct 2023 09:41:04 -0600 Subject: [PATCH] Update G4G Colab notebook --- examples/workshops/.jupytext.toml | 14 ------- examples/workshops/G4G_2023.ipynb | 61 +++++++++++++++++++++++++------ geemap/toolbar.py | 41 +++++++++++++-------- 3 files changed, 75 insertions(+), 41 deletions(-) delete mode 100644 examples/workshops/.jupytext.toml diff --git a/examples/workshops/.jupytext.toml b/examples/workshops/.jupytext.toml deleted file mode 100644 index 9e8db5e8ff..0000000000 --- a/examples/workshops/.jupytext.toml +++ /dev/null @@ -1,14 +0,0 @@ -# Install jupytext using: conda install jupytext -c conda-forge -# Always pair ipynb notebooks to md files. -# formats = "ipynb,md" -formats = "ipynb,myst" - -# jupytext --to ipynb *.md # convert all .md files to notebooks with no outputs -# jupytext --to ipynb --execute *.md # convert all .md files to notebooks and execute them -# jupytext --set-formats ipynb,md --execute *.md # convert all .md files to paired notebooks and execute them -# jupytext --to md *.ipynb # convert all .ipynb files to .md files -# jupytext --to myst *.ipynb # convert all .ipynb files to myst files - -# convert notebooks to rst https://nbconvert.readthedocs.io/en/latest/usage.html#convert-rst -# jupyter nbconvert *.ipynb --to rst -# convert md to rst: m2r *.md diff --git a/examples/workshops/G4G_2023.ipynb b/examples/workshops/G4G_2023.ipynb index 1a404bbcd6..e8fde8604e 100644 --- a/examples/workshops/G4G_2023.ipynb +++ b/examples/workshops/G4G_2023.ipynb @@ -40,15 +40,9 @@ "\n", "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/gee-community/geemap/blob/master/docs/workshops/G4G_2023.ipynb)\n", "\n", - "## Change Colab dark theme\n", - "\n", - "Currently, ipywidgets does not work well with Colab dark theme. It is recommended that you change Colab to the light theme.\n", - "\n", - "![](https://i.imgur.com/EJ0GDP8.png)\n", - "\n", "### Install geemap\n", "\n", - "Uncomment the following line to install geemap if you are running this notebook in Google Colab." + "The geemap package is pre-installed in Google Colab and is updated to the latest minor or major release every few weeks. Some optional dependencies of geemap being used by this notebook are not pre-installed in Colab. Uncomment the following line to install geemap and some optional dependencies." ] }, { @@ -60,11 +54,28 @@ "# %pip install -U \"geemap[workshop]\"" ] }, + { + "cell_type": "markdown", + "id": "b4286b8d", + "metadata": {}, + "source": [ + "Note that some geemap features do not work properly with Google Colab. If you are familiar with [Anaconda](https://www.anaconda.com/distribution/#download-section) or [Miniconda](https://docs.conda.io/en/latest/miniconda.html), it is recommended to create a new conda environment to install geemap and its optional dependencies on your local computer. \n", + "\n", + "```bash\n", + "conda create -n gee python=3.10\n", + "conda activate gee\n", + "conda install -c conda-forge mamba\n", + "mamba install -c conda-forge geemap pygis\n", + "```" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Import libraries" + "### Import libraries\n", + "\n", + "Import the earthengine-api and geemap." ] }, { @@ -755,6 +766,14 @@ "m" ] }, + { + "cell_type": "markdown", + "id": "82bf15c5", + "metadata": {}, + "source": [ + "Set plotting options for Landsat." + ] + }, { "cell_type": "code", "execution_count": null, @@ -764,6 +783,24 @@ "m.set_plot_options(add_marker_cluster=True, overlay=True)" ] }, + { + "cell_type": "markdown", + "id": "d99f573d", + "metadata": {}, + "source": [ + "Set plotting options for Hyperion." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fd118eb3", + "metadata": {}, + "outputs": [], + "source": [ + "m.set_plot_options(add_marker_cluster=True, plot_type=\"bar\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -999,7 +1036,7 @@ "\n", "### Split-panel maps\n", "\n", - "Create a split map with basemaps." + "Create a split map with basemaps. Note that ipyleaflet has a bug with the SplitControl. You can't pan the map, which should be resolved in the next ipyleaflet release." ] }, { @@ -1044,7 +1081,7 @@ "source": [ "### Linked maps\n", "\n", - "Create a 2x2 linked map for visualizing Sentinel-2 imagery with different band combinations." + "Create a 2x2 linked map for visualizing Sentinel-2 imagery with different band combinations. Note that this feature does not work properly with Colab. Panning one map would not pan other maps. " ] }, { @@ -1115,7 +1152,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Create a timeseries inspector for NLCD." + "Create a timeseries inspector for NLCD. Note that ipyleaflet has a bug with the SplitControl. You can't pan the map, which should be resolved in the next ipyleaflet release." ] }, { @@ -3203,7 +3240,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.10.12" } }, "nbformat": 4, diff --git a/geemap/toolbar.py b/geemap/toolbar.py index 701fb9126e..d839dc1fb4 100644 --- a/geemap/toolbar.py +++ b/geemap/toolbar.py @@ -728,7 +728,7 @@ def generate_chart(dict_values, chart_point): del plot_options["title"] m.default_style = {"cursor": "crosshair"} except Exception as e: - if not hasattr(map, "_plot_widget"): + if not hasattr(m, "_plot_widget"): m._plot_widget = None if m._plot_widget is not None: with m._plot_widget: @@ -755,15 +755,24 @@ def handle_interaction(**kwargs): plot_options["sample_scale"] is not None ): sample_scale = plot_options["sample_scale"] - dict_values_tmp = ( - ee_object.sample(xy, scale=sample_scale) - .first() - .toDictionary() - .getInfo() - ) - b_names = ee_object.bandNames().getInfo() - dict_values = dict(zip(b_names, [dict_values_tmp[b] for b in b_names])) - generate_chart(dict_values, latlon) + try: + dict_values_tmp = ( + ee_object.sample(xy, scale=sample_scale) + .first() + .toDictionary() + .getInfo() + ) + b_names = ee_object.bandNames().getInfo() + dict_values = dict(zip(b_names, [dict_values_tmp[b] for b in b_names])) + generate_chart(dict_values, latlon) + except Exception as e: + if hasattr(m, "_plot_widget"): + m._plot_widget.clear_output() + with m._plot_widget: + print("No data for the clicked location.") + else: + pass + m.default_style = {"cursor": "crosshair"} m.on_interaction(handle_interaction) @@ -824,10 +833,8 @@ def close_click(change): @map_widgets.Theme.apply class SearchDataGUI(widgets.HBox): - def __init__(self, m, **kwargs): - - # Adds search button and search box + # Adds search button and search box from .conversion import js_snippet_to_py @@ -840,7 +847,9 @@ def __init__(self, m, **kwargs): value=False, tooltip="Search location/data", icon="globe", - layout=widgets.Layout(width="28px", height="28px", padding="0px 0px 0px 4px"), + layout=widgets.Layout( + width="28px", height="28px", padding="0px 0px 0px 4px" + ), ) search_type = widgets.ToggleButtons( @@ -888,7 +897,9 @@ def get_ee_example(asset_id): pkg_dir = os.path.dirname( pkg_resources.resource_filename("geemap", "geemap.py") ) - with open(os.path.join(pkg_dir, "data/gee_f.json"), encoding="utf-8") as f: + with open( + os.path.join(pkg_dir, "data/gee_f.json"), encoding="utf-8" + ) as f: functions = json.load(f) details = [ dataset["code"]