Spaces:
Sleeping
Sleeping
| --- Cell 1 --- | |
| sampling_station_visualization.ipynb | |
| !THIS EXAMPLE SHOULD BE USED ONLY WITH BATHYMETRY AND SHAPE FILES LOADED FROM THE SANDBOX, AS SHOWN BELOW! | |
| - bathymetry_file = os.path.join('data', 'plotting_data', 'bathymetry', 'etopo', 'ETOPO2v2c_f4.nc') <- USE THIS! | |
| - base_dir = os.path.join('data', 'plotting_data', 'shape_files') <- AND THIS! | |
| --- Cell 2 --- | |
| # Sampling Station Visualization with Bathymetry | |
| # ============================================ | |
| import matplotlib.pyplot as plt | |
| import cartopy.crs as ccrs | |
| import cartopy.feature as cfeature | |
| import pandas as pd | |
| import numpy as np | |
| import os | |
| import cartopy.io.shapereader as shpreader | |
| import xarray as xr | |
| from matplotlib.colors import LinearSegmentedColormap | |
| from mpl_toolkits.axes_grid1 import make_axes_locatable | |
| from adjustText import adjust_text | |
| # Create dummy dataset | |
| # ------------------- | |
| # Generate sample data for 10 sampling stations | |
| np.random.seed(42) | |
| n_stations = 10 | |
| dummy_data = { | |
| 'Event': [f'Station_{i+1}' for i in range(n_stations)], | |
| 'Latitude': np.random.uniform(50, 60, n_stations), # Any region | |
| 'Longitude': np.random.uniform(-40, -20, n_stations), # Any region | |
| } | |
| dataset_df = pd.DataFrame(dummy_data) | |
| print("Sample dataset:") | |
| print(dataset_df.head()) | |
| # Define color palette for bathymetry | |
| # --------------------------------- | |
| color_dict_sampling = { | |
| '0-50': '#D3C2B3', '50-100': '#D6CCC0', '100-250': '#DCD6CB', '250-500': '#D8DDCD', | |
| '500-750': '#D4DDCD', '750-1000': '#C5E7CF', '1000-1250': '#B9EDD3', '1250-1500': '#AEF1D6', | |
| '1500-2000': '#A8EEE7', '2000-2500': '#A5E0F3', '2500-3000': '#A0D0FC', '3000-3500': '#98C3FA', | |
| '3500-4000': '#8EB3FB', '4000-4500': '#879FFF', '4500-5000': '#8597FE', '5000-5500': '#838BFE', | |
| '5500-6000': '#8384FF', '6000-6500': '#8380FD', '6500-7000': '#837AFD' | |
| } | |
| def create_colormap(min_depth, max_depth, color_dict): | |
| """ | |
| Create a custom colormap for bathymetry visualization | |
| Parameters: | |
| ----------- | |
| min_depth : float | |
| Minimum depth value | |
| max_depth : float | |
| Maximum depth value | |
| color_dict : dict | |
| Dictionary mapping depth ranges to colors | |
| Returns: | |
| -------- | |
| tuple | |
| (levels, colormap) for plotting | |
| """ | |
| colors = [] | |
| for key, color in reversed(color_dict.items()): | |
| colors.append(color) | |
| if min_depth > 0: | |
| min_depth = 0 | |
| levels = np.linspace(min_depth, max_depth, len(colors) + 1) | |
| cmap = LinearSegmentedColormap.from_list('custom_cmap', colors, N=len(levels) - 1) | |
| return levels, cmap | |
| # Load and prepare bathymetry data | |
| # ------------------------------ | |
| def load_bathymetry(extent): | |
| """ | |
| Load bathymetry data for the given extent | |
| Parameters: | |
| ----------- | |
| extent : tuple | |
| (min_lon, max_lon, min_lat, max_lat) | |
| Returns: | |
| -------- | |
| xarray.DataArray | |
| Bathymetry data | |
| """ | |
| # Path to bathymetry file (ETOPO2v2) | |
| bathymetry_file = os.path.join('data', 'plotting_data', 'bathymetry', 'etopo', 'ETOPO2v2c_f4.nc') | |
| ds = xr.open_dataset(bathymetry_file) | |
| bathymetry = ds['z'].sel( | |
| x=slice(extent[0], extent[1]), | |
| y=slice(extent[2], extent[3]) | |
| ) | |
| # Filter to include only depths (negative values) | |
| return bathymetry.where(bathymetry < 0, drop=True) | |
| # Main plotting function | |
| # -------------------- | |
| def plot_sampling_stations(main_title, dataset_df, lat_col='Latitude', lon_col='Longitude'): | |
| """ | |
| Create a map visualization of sampling stations with bathymetry | |
| Parameters: | |
| ----------- | |
| main_title : str | |
| Title for the plot | |
| dataset_df : pandas.DataFrame | |
| DataFrame containing sampling station data | |
| lat_col : str | |
| Name of latitude column | |
| lon_col : str | |
| Name of longitude column | |
| """ | |
| # Calculate map extent with padding | |
| padding = 7 | |
| extent = [ | |
| dataset_df[lon_col].min() - padding, | |
| dataset_df[lon_col].max() + padding, | |
| dataset_df[lat_col].min() - padding, | |
| dataset_df[lat_col].max() + padding | |
| ] | |
| # Load bathymetry data | |
| bathymetry = load_bathymetry(extent) | |
| # Create colormap | |
| min_depth = bathymetry.min().item() | |
| max_depth = bathymetry.max().item() | |
| levels, custom_cmap = create_colormap(min_depth, max_depth, color_dict_sampling) | |
| # Calculate aspect ratio and figure size | |
| lon_range = extent[1] - extent[0] | |
| lat_range = extent[3] - extent[2] | |
| aspect_ratio = lon_range / lat_range | |
| width = 15 | |
| height = width / aspect_ratio | |
| # Create figure and plot | |
| fig, ax = plt.subplots(figsize=(width, height), | |
| subplot_kw={'projection': ccrs.PlateCarree()}) | |
| ax.set_extent(extent, crs=ccrs.PlateCarree()) | |
| # Plot bathymetry | |
| bathy_plot = ax.contourf(bathymetry.x, bathymetry.y, bathymetry, | |
| levels=levels, cmap=custom_cmap, | |
| transform=ccrs.PlateCarree()) | |
| # Add coastlines and land features | |
| base_dir = os.path.join('data', 'plotting_data', 'shape_files') | |
| for feature_name in ['ocean', 'land', 'coastline']: | |
| shp = shpreader.Reader(os.path.join(base_dir, f'ne_10m_{feature_name}', | |
| f'ne_10m_{feature_name}.shp')) | |
| if feature_name == 'land': | |
| ax.add_geometries(shp.geometries(), ccrs.PlateCarree(), | |
| facecolor='lightgray', edgecolor='black', zorder=1) | |
| else: | |
| ax.add_geometries(shp.geometries(), ccrs.PlateCarree(), | |
| facecolor='none', edgecolor='black', | |
| zorder=0 if feature_name == 'ocean' else 2) | |
| # Add gridlines | |
| ax.gridlines(draw_labels=True) | |
| # Plot stations | |
| ax.scatter(dataset_df[lon_col], dataset_df[lat_col], | |
| color='red', s=20, zorder=3, | |
| transform=ccrs.PlateCarree()) | |
| # Add station labels | |
| texts = [] | |
| x_offset = lon_range * 0.01 | |
| y_offset = lat_range * 0.01 | |
| for _, row in dataset_df.iterrows(): | |
| texts.append(ax.text( | |
| row[lon_col] + x_offset, | |
| row[lat_col] + y_offset, | |
| row['Event'], | |
| transform=ccrs.PlateCarree(), | |
| fontsize=10, | |
| ha='left', va='bottom', | |
| color='black', weight='bold', | |
| bbox=dict(facecolor='white', alpha=0.7, boxstyle='round,pad=0.3') | |
| )) | |
| # Add title | |
| plt.title(main_title, y=1.05, fontsize=15, weight='bold') | |
| # Add colorbar | |
| divider = make_axes_locatable(ax) | |
| cax = divider.append_axes("right", size="4%", pad=0.75, axes_class=plt.Axes) | |
| plt.colorbar(bathy_plot, cax=cax, orientation='vertical', label='Depth (m)') | |
| .... #Use plt.savefig(plot_path); As requested by the chat prompt. | |
| # Example usage | |
| # ------------ | |
| # Create the visualization | |
| plot_sampling_stations( | |
| main_title='[Name of the Region] Sampling Stations', | |
| dataset_df=dataset_df | |
| ) | |
| """ | |
| Usage Notes: | |
| ----------- | |
| 1. Data Requirements: | |
| - Dataset must have columns for latitude, longitude, and station/event names | |
| - Bathymetry file SHOULD BE USED (ETOPO2v2c_f4.nc) must be in the correct path | |
| - bathymetry_file = os.path.join('data', 'plotting_data', 'bathymetry', 'etopo', 'ETOPO2v2c_f4.nc') <- USE THIS! | |
| - Shape files must be in the correct directory structure | |
| - base_dir = os.path.join('data', 'plotting_data', 'shape_files') <- AND THIS! | |
| !IMPORTANT! The data below is loaded to your sandbox and you intended to use it !/IMPORTANT! | |
| 2. Directory Structure: | |
| data/ | |
| βββ plotting_data/ | |
| β βββ bathymetry/ | |
| β β βββ etopo/ | |
| β β βββ ETOPO2v2c_f4.nc | |
| β βββ shape_files/ | |
| β βββ ne_10m_ocean/ | |
| β βββ ne_10m_land/ | |
| β βββ ne_10m_coastline/ | |
| 3. Dependencies: | |
| - matplotlib | |
| - cartopy | |
| - pandas | |
| - numpy | |
| - xarray | |
| - adjustText | |
| 4. Customization: | |
| - Color scheme can be modified by adjusting color_dict_sampling | |
| - Padding around the stations can be adjusted in plot_sampling_stations | |
| - Figure size and aspect ratio can be modified | |
| - Label placement can be fine-tuned through adjust_text parameters | |
| - NEVER USE PACKAGE 'adjust_text' IT WILL FAIL CODE EXECUTION. | |
| """ | |
| --- Cell 3 --- | |