Source code for voxcity.visualizer.grids

from __future__ import annotations

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.colors import ListedColormap, BoundaryNorm
import contextily as ctx

from ..geoprocessor.raster import grid_to_geodataframe
from ..utils.lc import get_land_cover_classes


[docs] def visualize_landcover_grid_on_basemap(landcover_grid, rectangle_vertices, meshsize, source='Standard', alpha=0.6, figsize=(12, 8), basemap='CartoDB light', show_edge=False, edge_color='black', edge_width=0.5): land_cover_classes = get_land_cover_classes(source) gdf = grid_to_geodataframe(landcover_grid, rectangle_vertices, meshsize) colors = [(r/255, g/255, b/255) for (r,g,b) in land_cover_classes.keys()] cmap = ListedColormap(colors) bounds = np.arange(len(colors) + 1) norm = BoundaryNorm(bounds, cmap.N) gdf_web = gdf.to_crs(epsg=3857) fig, ax = plt.subplots(figsize=figsize) gdf_web.plot(column='value', ax=ax, alpha=alpha, cmap=cmap, norm=norm, legend=True, legend_kwds={'label': 'Land Cover Class', 'ticks': bounds[:-1] + 0.5, 'boundaries': bounds, 'format': lambda x, p: list(land_cover_classes.values())[int(x)]}, edgecolor=edge_color if show_edge else 'none', linewidth=edge_width if show_edge else 0) basemaps = { 'CartoDB dark': ctx.providers.CartoDB.DarkMatter, 'CartoDB light': ctx.providers.CartoDB.Positron, 'CartoDB voyager': ctx.providers.CartoDB.Voyager, 'CartoDB light no labels': ctx.providers.CartoDB.PositronNoLabels, 'CartoDB dark no labels': ctx.providers.CartoDB.DarkMatterNoLabels, } ctx.add_basemap(ax, source=basemaps[basemap]) ax.set_axis_off() plt.tight_layout(); plt.show()
[docs] def visualize_numerical_grid_on_basemap(grid, rectangle_vertices, meshsize, value_name="value", cmap='viridis', vmin=None, vmax=None, alpha=0.6, figsize=(12, 8), basemap='CartoDB light', show_edge=False, edge_color='black', edge_width=0.5): gdf = grid_to_geodataframe(grid, rectangle_vertices, meshsize) gdf_web = gdf.to_crs(epsg=3857) fig, ax = plt.subplots(figsize=figsize) gdf_web.plot(column='value', ax=ax, alpha=alpha, cmap=cmap, vmin=vmin, vmax=vmax, legend=True, legend_kwds={'label': value_name}, edgecolor=edge_color if show_edge else 'none', linewidth=edge_width if show_edge else 0) basemaps = { 'CartoDB dark': ctx.providers.CartoDB.DarkMatter, 'CartoDB light': ctx.providers.CartoDB.Positron, 'CartoDB voyager': ctx.providers.CartoDB.Voyager, 'CartoDB light no labels': ctx.providers.CartoDB.PositronNoLabels, 'CartoDB dark no labels': ctx.providers.CartoDB.DarkMatterNoLabels, } ctx.add_basemap(ax, source=basemaps[basemap]) ax.set_axis_off() plt.tight_layout(); plt.show()
[docs] def visualize_numerical_gdf_on_basemap(gdf, value_name="value", cmap='viridis', vmin=None, vmax=None, alpha=0.6, figsize=(12, 8), basemap='CartoDB light', show_edge=False, edge_color='black', edge_width=0.5, input_crs=None): if gdf.crs is None: if input_crs is not None: gdf = gdf.set_crs(input_crs, allow_override=True) else: try: minx, miny, maxx, maxy = gdf.total_bounds looks_like_lonlat = (-180.0 <= minx <= 180.0 and -180.0 <= maxx <= 180.0 and -90.0 <= miny <= 90.0 and -90.0 <= maxy <= 90.0) except Exception: looks_like_lonlat = False if looks_like_lonlat: gdf = gdf.set_crs("EPSG:4326", allow_override=True) else: raise ValueError("Input GeoDataFrame has no CRS. Provide 'input_crs' or set gdf.crs.") gdf_web = gdf.to_crs(epsg=3857) if str(gdf.crs) != 'EPSG:3857' else gdf fig, ax = plt.subplots(figsize=figsize) gdf_web.plot(column=value_name, ax=ax, alpha=alpha, cmap=cmap, vmin=vmin, vmax=vmax, legend=True, legend_kwds={'label': value_name}, edgecolor=edge_color if show_edge else 'none', linewidth=edge_width if show_edge else 0) basemaps = { 'CartoDB dark': ctx.providers.CartoDB.DarkMatter, 'CartoDB light': ctx.providers.CartoDB.Positron, 'CartoDB voyager': ctx.providers.CartoDB.Voyager, 'CartoDB light no labels': ctx.providers.CartoDB.PositronNoLabels, 'CartoDB dark no labels': ctx.providers.CartoDB.DarkMatterNoLabels, } ctx.add_basemap(ax, source=basemaps[basemap]) ax.set_axis_off() plt.tight_layout(); plt.show()
[docs] def visualize_point_gdf_on_basemap(point_gdf, value_name='value', **kwargs): import contextily as ctx defaults = { 'figsize': (12, 8), 'colormap': 'viridis', 'markersize': 20, 'alpha': 0.7, 'vmin': None, 'vmax': None, 'title': None, 'basemap_style': ctx.providers.CartoDB.Positron, 'zoom': 15 } settings = {**defaults, **kwargs} fig, ax = plt.subplots(figsize=settings['figsize']) point_gdf_web = point_gdf.to_crs(epsg=3857) point_gdf_web.plot(column=value_name, ax=ax, cmap=settings['colormap'], markersize=settings['markersize'], alpha=settings['alpha'], vmin=settings['vmin'], vmax=settings['vmax'], legend=True, legend_kwds={'label': value_name}) ctx.add_basemap(ax, source=settings['basemap_style'], zoom=settings['zoom']) if settings['title']: plt.title(settings['title']) ax.set_axis_off(); plt.tight_layout(); plt.show()
[docs] def visualize_land_cover_grid(grid, mesh_size, color_map, land_cover_classes): all_classes = list(land_cover_classes.values()) unique_classes = list(dict.fromkeys(all_classes)) grid_classes = [cls for cls in dict.fromkeys(np.asarray(grid, dtype=object).ravel()) if cls not in unique_classes] unique_classes.extend(grid_classes) colors = [color_map.get(cls, [0.0, 0.0, 0.0]) for cls in unique_classes] cmap = mcolors.ListedColormap(colors) bounds = np.arange(len(unique_classes) + 1) norm = mcolors.BoundaryNorm(bounds, cmap.N) class_to_num = {cls: i for i, cls in enumerate(unique_classes)} numeric_grid = np.vectorize(class_to_num.get, otypes=[float])(grid) plt.figure(figsize=(10, 10)) im = plt.imshow(numeric_grid, cmap=cmap, norm=norm, interpolation='nearest', origin='lower') cbar = plt.colorbar(im, ticks=bounds[:-1] + 0.5) cbar.set_ticklabels(unique_classes) plt.title(f'Land Use/Land Cover Grid (Mesh Size: {mesh_size}m)') plt.xlabel('Grid Cells (X)') plt.ylabel('Grid Cells (Y)') plt.show()
[docs] def visualize_numerical_grid(grid, mesh_size, title, cmap='viridis', label='Value', vmin=None, vmax=None): plt.figure(figsize=(10, 10)) plt.imshow(grid, cmap=cmap, vmin=vmin, vmax=vmax, origin='lower') plt.colorbar(label=label) plt.title(f'{title} (Mesh Size: {mesh_size}m)') plt.xlabel('Grid Cells (X)') plt.ylabel('Grid Cells (Y)') plt.show()