From 23425bbca51f314aa80b16f70e7e8b2db7532f7b Mon Sep 17 00:00:00 2001 From: Nils Lehmann <35272119+nilsleh@users.noreply.github.com> Date: Sun, 27 Feb 2022 21:01:23 +0100 Subject: [PATCH] Add plot method and data.py to Esri2020 dataset (#405) * add plot method and data.py * typo missed period * forgot data.py * Remove abc, add versionchanged * Update esri2020.py * fixed test and requested changes * Add uncompressed data file * add test coverage Co-authored-by: Caleb Robinson Co-authored-by: Adam J. Stewart --- tests/data/esri2020/data.py | 60 ++++++++++++++++++ ...1-composite-v03-supercell-v02-clip-v01.zip | Bin 4958 -> 5727 bytes .../00A_20200101-20210101.tif | Bin 4455 -> 5855 bytes tests/datasets/test_esri2020.py | 32 ++++++---- torchgeo/datasets/esri2020.py | 49 +++++++++++++- 5 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 tests/data/esri2020/data.py diff --git a/tests/data/esri2020/data.py b/tests/data/esri2020/data.py new file mode 100644 index 00000000000..9c3b110ad2d --- /dev/null +++ b/tests/data/esri2020/data.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 + +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import hashlib +import os +import random +import shutil + +import numpy as np +import rasterio + +np.random.seed(0) +random.seed(0) + +SIZE = 64 + + +files = [{"image": "N00E020_agb.tif"}, {"image": "N00E020_agb_err.tif"}] + + +def create_file(path: str, dtype: str, num_channels: int) -> None: + profile = {} + profile["driver"] = "GTiff" + profile["dtype"] = dtype + profile["count"] = num_channels + profile["crs"] = "epsg:4326" + profile["transform"] = rasterio.transform.from_bounds(0, 0, 1, 1, 1, 1) + profile["height"] = SIZE + profile["width"] = SIZE + profile["compress"] = "lzw" + profile["predictor"] = 2 + + Z = np.random.randint( + np.iinfo(profile["dtype"]).max, size=(1, SIZE, SIZE), dtype=profile["dtype"] + ) + src = rasterio.open(path, "w", **profile) + src.write(Z) + + +if __name__ == "__main__": + dir = "io-lulc-model-001-v01-composite-v03-supercell-v02-clip-v01" + tif_name = "00A_20200101-20210101.tif" + + if os.path.exists(dir): + shutil.rmtree(dir) + + os.makedirs(dir) + + # Create mask file + create_file(os.path.join(dir, tif_name), dtype="int8", num_channels=1) + + shutil.make_archive(dir, "zip", base_dir=dir) + + # Compute checksums + zipfilename = dir + ".zip" + with open(zipfilename, "rb") as f: + md5 = hashlib.md5(f.read()).hexdigest() + print(f"{zipfilename}: {md5}") diff --git a/tests/data/esri2020/io-lulc-model-001-v01-composite-v03-supercell-v02-clip-v01.zip b/tests/data/esri2020/io-lulc-model-001-v01-composite-v03-supercell-v02-clip-v01.zip index 217161b7a152ccb3511a781dbceaee9561095389..910c3c23d239b32259b560ddccc69922b65383f1 100644 GIT binary patch delta 5495 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 K)6J;<-Tn)t29kRK literal 4958 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 literal 4455 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 None: - url = os.path.join( - "tests", - "data", - "esri2020", - "io-lulc-model-001-v01-composite-v03-supercell-v02-clip-v01.zip", - ) - root = str(tmp_path) - shutil.copy(url, root) - Esri2020(root) - def test_getitem(self, dataset: Esri2020) -> None: x = dataset[dataset.bounds] assert isinstance(x, dict) @@ -65,6 +54,16 @@ def test_getitem(self, dataset: Esri2020) -> None: def test_already_extracted(self, dataset: Esri2020) -> None: Esri2020(root=dataset.root, download=True) + def test_not_extracted(self, tmp_path: Path) -> None: + url = os.path.join( + "tests", + "data", + "esri2020", + "io-lulc-model-001-v01-composite-v03-supercell-v02-clip-v01.zip", + ) + shutil.copy(url, tmp_path) + Esri2020(root=str(tmp_path)) + def test_not_downloaded(self, tmp_path: Path) -> None: with pytest.raises(RuntimeError, match="Dataset not found"): Esri2020(str(tmp_path), checksum=True) @@ -80,7 +79,14 @@ def test_or(self, dataset: Esri2020) -> None: def test_plot(self, dataset: Esri2020) -> None: query = dataset.bounds x = dataset[query] - dataset.plot(x["mask"]) + dataset.plot(x, suptitle="Test") + plt.close() + + def test_plot_prediction(self, dataset: Esri2020) -> None: + query = dataset.bounds + x = dataset[query] + x["prediction"] = x["mask"].clone() + dataset.plot(x, suptitle="Prediction") plt.close() def test_url(self) -> None: diff --git a/torchgeo/datasets/esri2020.py b/torchgeo/datasets/esri2020.py index 4d8c651a6a0..78ed789a795 100644 --- a/torchgeo/datasets/esri2020.py +++ b/torchgeo/datasets/esri2020.py @@ -3,18 +3,18 @@ """Esri 2020 Land Cover Dataset.""" -import abc import glob import os from typing import Any, Callable, Dict, Optional +import matplotlib.pyplot as plt from rasterio.crs import CRS from .geo import RasterDataset from .utils import download_url, extract_archive -class Esri2020(RasterDataset, abc.ABC): +class Esri2020(RasterDataset): """Esri 2020 Land Cover Dataset. The `Esri 2020 Land Cover dataset @@ -136,3 +136,48 @@ def _download(self) -> None: def _extract(self) -> None: """Extract the dataset.""" extract_archive(os.path.join(self.root, self.zipfile)) + + def plot( # type: ignore[override] + self, + sample: Dict[str, Any], + show_titles: bool = True, + suptitle: Optional[str] = None, + ) -> plt.Figure: + """Plot a sample from the dataset. + + Args: + sample: a sample returned by :meth:`RasterDataset.__getitem__` + show_titles: flag indicating whether to show titles above each panel + suptitle: optional string to use as a suptitle + + Returns: + a matplotlib Figure with the rendered sample + """ + mask = sample["mask"].squeeze() + ncols = 1 + + showing_predictions = "prediction" in sample + if showing_predictions: + prediction = sample["prediction"].squeeze() + ncols = 2 + + fig, axs = plt.subplots(nrows=1, ncols=ncols, figsize=(4 * ncols, 4)) + + if showing_predictions: + axs[0].imshow(mask) + axs[0].axis("off") + axs[1].imshow(prediction) + axs[1].axis("off") + if show_titles: + axs[0].set_title("Mask") + axs[1].set_title("Prediction") + else: + axs.imshow(mask) + axs.axis("off") + if show_titles: + axs.set_title("Mask") + + if suptitle is not None: + plt.suptitle(suptitle) + + return fig