pangaeagpt / data /examples_database /txt_docs /sampling_station_visualization.txt
dmpantiu
Add data folder
de15ddc
--- 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 ---