Source code for wrf_nlcd_lulc_converter.plotting

"""
Plotting utilities for WRF NLCD LULC converter.
"""

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from .mapping import LULCMapping
from .colormap import get_lulc_colormap, get_lulc_normalization, create_colorbar


[docs] def plot_coast(ax, houston=True, houston_color='k', houston_linewidth=0.5): """ Add coastlines and state boundaries to a cartopy plot. Parameters: ax: Cartopy axes object houston (bool): Whether to add Houston area outline houston_color (str): Color for Houston outline houston_linewidth (float): Line width for Houston outline """ # Add coastlines ax.add_feature(cfeature.COASTLINE, linewidth=0.5) ax.add_feature(cfeature.STATES, linewidth=0.3) ax.add_feature(cfeature.BORDERS, linewidth=0.5) if houston: # Add Houston area outline (approximate) houston_lon = [-95.5, -95.0, -95.0, -95.5, -95.5] houston_lat = [29.5, 29.5, 30.0, 30.0, 29.5] ax.plot(houston_lon, houston_lat, color=houston_color, linewidth=houston_linewidth, transform=ccrs.PlateCarree())
[docs] def plot_lulc_data(longitudes, latitudes, lulc_data, title="LULC Data", extent=None, save_path=None, dpi=150, show_plot=True): """ Plot LULC data with proper color mapping and labels. Parameters: longitudes (np.ndarray): Longitude coordinates latitudes (np.ndarray): Latitude coordinates lulc_data (np.ndarray): LULC class data title (str): Plot title extent (list): Map extent [lon_min, lon_max, lat_min, lat_max] save_path (str): Path to save the plot (optional) dpi (int): DPI for saved image show_plot (bool): Whether to display the plot """ # Get colormap and normalization cmap, _, _, vmin, vmax = get_lulc_colormap() # Create figure fig, ax = plt.subplots(1, 1, figsize=(15, 8), subplot_kw={'projection': ccrs.PlateCarree()}) # Plot LULC data using the exact colormap from the notebook out = ax.pcolormesh(longitudes, latitudes, lulc_data, cmap=cmap, vmin=vmin, vmax=vmax) # Add coastlines plot_coast(ax, houston=True, houston_color='k', houston_linewidth=0.5) # Add standardized colorbar create_colorbar(ax, out) # Set extent if provided if extent: ax.set_extent(extent) ax.set_title(title) # Save plot if path provided if save_path: plt.savefig(save_path, dpi=dpi, bbox_inches='tight') print(f"Plot saved to: {save_path}") if show_plot: plt.show() return fig, ax
[docs] def plot_urban_comparison(original_lulc, updated_lulc, longitudes, latitudes, title="Urban Area Comparison", save_path=None, dpi=150): """ Plot comparison of original vs updated urban areas. Parameters: original_lulc (np.ndarray): Original LULC data updated_lulc (np.ndarray): Updated LULC data longitudes (np.ndarray): Longitude coordinates latitudes (np.ndarray): Latitude coordinates title (str): Plot title save_path (str): Path to save the plot (optional) dpi (int): DPI for saved image """ # Get colormap and normalization cmap, labels, _, vmin, vmax = get_lulc_colormap() urban_classes = [21, 22, 23, 24, 25, 26] # Create figure with subplots and adjust for colorbar fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(22, 8), subplot_kw={'projection': ccrs.PlateCarree()}) # Plot original urban areas urban_mask_original = np.isin(original_lulc, urban_classes) urban_original = np.where(urban_mask_original, original_lulc, np.nan) out1 = ax1.pcolormesh(longitudes, latitudes, urban_original, cmap=cmap, vmin=vmin, vmax=vmax) plot_coast(ax1, houston=True, houston_color='k', houston_linewidth=0.5) ax1.set_title("Original Urban Areas") # Plot updated urban areas urban_mask_updated = np.isin(updated_lulc, urban_classes) urban_updated = np.where(urban_mask_updated, updated_lulc, np.nan) out2 = ax2.pcolormesh(longitudes, latitudes, urban_updated, cmap=cmap, vmin=vmin, vmax=vmax) plot_coast(ax2, houston=True, houston_color='k', houston_linewidth=0.5) ax2.set_title("Updated Urban Areas") # Add colorbar with proper positioning cbar = plt.colorbar(out1, ax=[ax1, ax2], orientation='vertical', fraction=0.046, pad=0.04, ticks=np.arange(1, 41)) cbar.set_label('LULC Class') cbar.set_ticks(np.arange(1, 41)) cbar.set_ticklabels([f"{i+1}: {labels[i]}" for i in range(40)]) plt.suptitle(title) # Adjust layout to prevent overlapping plt.tight_layout() # Save plot if path provided if save_path: plt.savefig(save_path, dpi=dpi, bbox_inches='tight') print(f"Comparison plot saved to: {save_path}") plt.show() return fig, (ax1, ax2)
[docs] def plot_domain_info(wrf_info, title="WRF Domain Information", save_path=None, dpi=150): """ Plot WRF domain information with LULC data. Parameters: wrf_info (dict): WRF domain information from extract_wrf_domain_info title (str): Plot title save_path (str): Path to save the plot (optional) dpi (int): DPI for saved image """ longitudes = wrf_info['longitudes'] latitudes = wrf_info['latitudes'] lulc_data = wrf_info['lu_index'] domain = wrf_info['domain'] # Set extent based on domain extent = [domain['lon_min'], domain['lon_max'], domain['lat_min'], domain['lat_max']] return plot_lulc_data(longitudes, latitudes, lulc_data, title, extent, save_path, dpi)
[docs] def create_sample_plot(): """ Create a sample plot for demonstration purposes. Returns: str: Path to the saved plot """ # Get colormap and normalization cmap, _, _, vmin, vmax = get_lulc_colormap() # Sample domain (Houston area) lon_min, lon_max = -96.5, -94.0 lat_min, lat_max = 28.9, 30.5 # Create grid nx, ny = 100, 80 longitudes = np.linspace(lon_min, lon_max, nx) latitudes = np.linspace(lat_min, lat_max, ny) # Create sample LULC data lulc_data = np.random.randint(1, 41, size=(ny, nx)) # Add some urban areas urban_classes = [21, 22, 23, 24, 25, 26] urban_mask = np.random.random((ny, nx)) < 0.1 # 10% urban lulc_data[urban_mask] = np.random.choice(urban_classes, size=np.sum(urban_mask)) # Plot and save save_path = "sample_lulc_plot.png" plot_lulc_data(longitudes, latitudes, lulc_data, title="Sample LULC Data (Houston Area)", extent=[lon_min, lon_max, lat_min, lat_max], save_path=save_path, show_plot=False) return save_path