Spaces:
Sleeping
Sleeping
File size: 8,264 Bytes
de15ddc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
--- 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 ---
|