From cd7469e27227e5d0fbe44b071926dc459d85cdd0 Mon Sep 17 00:00:00 2001 From: Callum Rollo Date: Thu, 12 Jun 2025 11:02:36 +0200 Subject: [PATCH] interactive maps work with list of datasets --- glidertest/interactive.py | 58 ++++++++++++++++++++++----------------- tests/test_interactive.py | 5 +++- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/glidertest/interactive.py b/glidertest/interactive.py index 7ff81e0..5a84e48 100644 --- a/glidertest/interactive.py +++ b/glidertest/interactive.py @@ -7,14 +7,14 @@ import matplotlib.pyplot as plt -def mission_map(ds): +def mission_map(ds_list): """ Makes an interactive folium map of a glider mission. Needs to run in a jupyter notebook Parameters ---------- - ds: xarray.DataSet - OG1 dataset of a glider mission + ds_list: xarray.DataSet or list of xarray.DataSets + OG1 dataset of a glider mission. can pass a list of missions Returns ------- @@ -25,35 +25,43 @@ def mission_map(ds): ----- Original author: Callum Rollo """ - _check_necessary_variables(ds, ["LONGITUDE", "LATITUDE", "DIVE_NUM"]) + if type(ds_list) is not list: + ds_list = [ds_list] + for ds in ds_list: + _check_necessary_variables(ds, ["LONGITUDE", "LATITUDE", "DIVE_NUM"]) df = ds.to_pandas()[["LONGITUDE", "LATITUDE", "DIVE_NUM"]].groupby("DIVE_NUM").median() - coordinates = [[lat, lon] for lat, lon in zip(ds['LATITUDE'].values, ds['LONGITUDE'].values)] - if len(coordinates) > 5000: - coordinates = coordinates[::int(np.ceil(len(coordinates) / 5000))] - df['DIVE_NUM'] = df.index m = folium.Map(location=[df.LATITUDE.mean(), df.LONGITUDE.mean()], zoom_start=8, tiles="cartodb positron") folium.WmsTileLayer( url="https://ows.emodnet-bathymetry.eu/wms", - layers= 'mean_atlas_land', + layers='mean_atlas_land', attr='EMODnet bathymetry' ).add_to(m) - - folium.PolyLine( - locations=coordinates, - color="red", - weight=5, - tooltip="Glider track", - ).add_to(m) - - for i, row in df.iterrows(): - folium.CircleMarker( - location=[row['LATITUDE'], row['LONGITUDE']], - tooltip=f"Dive {int(row['DIVE_NUM'])}", - color= 'black', - fillOpacity= 1, - fillColor= "red", - weight = 2, + color_cycle = ["red", "yellow", "green", "black", "pink"] + for i, ds in enumerate(ds_list): + df = ds.to_pandas()[["LONGITUDE", "LATITUDE", "DIVE_NUM"]].groupby("DIVE_NUM").median() + df = df.dropna() + df_points = ds.to_pandas()[["LONGITUDE", "LATITUDE"]].dropna() + coordinates = [[lat, lon] for lat, lon in zip(df_points['LATITUDE'], df_points['LONGITUDE'])] + if len(coordinates) > 5000: + coordinates = coordinates[::int(np.ceil(len(coordinates) / 5000))] + df['DIVE_NUM'] = df.index + + folium.PolyLine( + locations=coordinates, + color=color_cycle[i], + weight=5, + tooltip=f"{ds.attrs['id']}", ).add_to(m) + + for j, row in df.iterrows(): + folium.CircleMarker( + location=[row['LATITUDE'], row['LONGITUDE']], + tooltip=f"Dive {int(row['DIVE_NUM'])}", + color= 'black', + fillOpacity= 1, + fillColor= color_cycle[i], + weight = 2, + ).add_to(m) return m def interactive_profile(ds): diff --git a/tests/test_interactive.py b/tests/test_interactive.py index 7482cbc..22aeb0e 100644 --- a/tests/test_interactive.py +++ b/tests/test_interactive.py @@ -3,4 +3,7 @@ def test_mission_map(): ds = fetchers.load_sample_dataset() - interactive.mission_map(ds) \ No newline at end of file + interactive.mission_map(ds) + dsa = fetchers.load_sample_dataset(dataset_name="sg638_20191205T121839_delayed.nc") + dsa['DIVE_NUM'] = dsa['divenum'].copy() + interactive.mission_map([ds, dsa])