def plot(self, flush_cache=True, norm=True, clip_percentage=(0.02, 0.98), clip_min_max=None, log=False, rescale_percentage=None, bands=None, ax=None, title=None, cmap=None, figsize=None): """Plot the raster object. Parameters ---------- flush_cache: bool. Flush the cached processed result for quick plotting. norm: bool, optional, default: True Normalize the image for showing. clip_percentage: tuple of float, optional, default: (0.02, 0.98) The percentage to cut the data in head and tail e.g. (0.02, 0.98) log: bool, optional, default: False Get the log value of data to show the image. rescale_percentage: float, optional The percentage to recale (resize) the image for efficient showing. bands: list, optional Which bands to plot. Length of bands should be 1, 3 or 4. If 3 bands is used, each of them will be defined as rgb bands. If the forth band is used, it will be the opacity value. ax: matplotlib.axes._subplots.AxesSubplot, optional On which ax the raster will be plot. title: str, optional The title of the histgram. cmap: str, optional See Colormaps in Matplotlib https://matplotlib.org/3.1.0/tutorials/colors/colormaps.html. figsize: tuple, optional Width and height of the histgram e.g.(10, 10). """ if bands is None: bands = [0, 1, 2] if self.bands >= 3 else [0] assert type(bands) is list, "type of bands should be list" assert len(bands) in [1, 3, 4], "length of bands should be 1, 3 or 4" if (self.cache_data_for_plot is None) or flush_cache: # reshape to valid shape for matplotlib if len(bands) == 1: data = self.data[:, :, bands[0]] else: data = self.data[:, :, bands] # deal with no data data = data.astype(np.float) data[data == self.no_data_value] = np.nan # detect single value if len(np.unique(data[~np.isnan(data)])) == 1: norm = False log = False clip_percentage = None # clip_percentage & clip_min_max if clip_percentage is not None: assert not ( clip_percentage is not None and clip_min_max is not None ), "should not set clip_percentage and clip_min_max at the same time!" assert len( clip_percentage) == 2, "clip_percentage two element tuple" data = tgp.Normalizer().clip_by_percentage( data, clip_percentage=clip_percentage) elif clip_min_max is not None: assert len(clip_min_max) == 2, "clip_min_max two element tuple" data = tgp.Normalizer().clip_by_min_max(data, min_max=clip_min_max) # log if log: if data[~np.isnan(data)].min() < 0: data -= data[~np.isnan(data)].min() data[~np.isnan(data)] = np.log(data[~np.isnan(data)] + 10**-6) # normalize if norm: data = tgp.Normalizer().fit_transform(data) if rescale_percentage is not None: import cv2 data = cv2.resize(data, (int(self.cols * rescale_percentage), int(self.rows * rescale_percentage))) self.cache_data_for_plot = data else: data = self.cache_data_for_plot # flip xy c, a, b, f, d, e = self.geo_transform # lng = a * col + b * row + c # lat = d * col + e * row + f # a = d(lng) / d(col) # b = d(lng) / d(row) # d = d(lat) / d(col) # e = d(lat) / d(row) if (np.abs(a) > np.abs(d)) and (np.abs(e) > np.abs(b)): lng_res, lat_res = a, e elif (np.abs(d) > np.abs(a)) and ( np.abs(b) > np.abs(e) ): # if d > a, 1 col move contribute more on lat, less on lng data = np.flipud(np.rot90(data)) lng_res, lat_res = d, b else: assert False, "not acceptable geotransform" if lng_res < 0: # general lng_res > 0 data = np.fliplr(data) if lat_res > 0: # general lat_res < 0 data = np.flipud(data) # plotting if ax is not None: img = ax.imshow(data, extent=self.extent_for_plot, cmap=cmap) ax.set_title(title) else: if figsize is not None: plt.figure(figsize=figsize) img = plt.imshow(data, extent=self.extent_for_plot, cmap=cmap) plt.title(title) plt.show() return img
def hist(self, norm=False, clip_percentage=None, log=False, bands=None, ax=None, title=None, figsize=None): """plot digital value histgram (distribution) of raster object. Parameters ---------- norm: bool, optional, default: False Normalize the image for showing. clip_percentage: tuple of float, optional The percentage to cut the data in head and tail e.g. (0.02, 0.98) log: bool, optional, default: False Use the log value to plot the histgram. bands: list, optional Which bands to plot. if bands==None, use values from all bands. ax: matplotlib.axes._subplots.AxesSubplot, optional On which ax the raster will be plot. title: str, optional The title of the histgram. figsize: tuple, optional Width and height of the histgram e.g.(10, 10). """ if bands is None: data = self.data[self.data != self.no_data_value].flatten() else: data = self.data[:, :, bands] data = data[data != self.no_data_value].flatten() # clip_percentage if clip_percentage is not None: assert len( clip_percentage) == 2, "clip_percentage two element tuple" idx_st = int(len(data.flatten()) * clip_percentage[0]) idx_end = int(len(data.flatten()) * clip_percentage[1]) X_sorted = np.sort(data.flatten()) data_min = X_sorted[idx_st] data_max = X_sorted[idx_end] data[data < data_min] = data_min data[data > data_max] = data_max # log if log: data = np.log(data) # normalize if norm: data = tgp.Normalizer().fit_transform( data, clip_percentage=clip_percentage) if ax is not None: ax.hist(data) ax.set_title(title) else: if figsize is not None: plt.figure(figsize=figsize) plt.hist(data) plt.title(title) plt.show()