Notebook#
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
import hvplot.pandas
import geopandas as gpd
import geoviews as gv
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from IPython.display import display
import urllib.request
from pathlib import Path
file_name = "nearest_nexrad.py"
url = "https://raw.githubusercontent.com/syedhamidali/test_scripts/master/nearest_nexrad.py"
if not Path(file_name).is_file():
urllib.request.urlretrieve(url, file_name)
import nearest_nexrad as nrnx
print(nrnx.get_nexrad_location("KGWX"))
(33.89667, -88.32889, 476)
sites = nrnx.nearest_sites(33.89667, -88.32889, 5).reset_index(drop=True)
display(sites)
ID | lat | lon | elev | distance | |
---|---|---|---|---|---|
0 | KGWX | 33.89667 | -88.32889 | 476.0 | 0.000000 |
1 | KBMX | 33.17194 | -86.76972 | 645.0 | 1.719373 |
2 | TMEM | 34.88670 | -90.00070 | 483.0 | 1.942964 |
3 | KNQA | 35.34472 | -89.87333 | 282.0 | 2.117107 |
4 | KDGX | 32.28000 | -89.98444 | -99999.0 | 2.313972 |
df = pd.read_excel("Data_availability_PERiLS.xlsx")
df.drop([9, 10, 11], inplace=True)
df.reset_index(drop=True, inplace=True)
df
Instrument | Lon | Lat | Range[m] | IOP | Start_Time | End_Time | |
---|---|---|---|---|---|---|---|
0 | COW1 | -87.946000 | 32.810980 | 88443.41 | IOP1 | 2022-03-22 17:04:44 | 2022-03-22 23:03:40 |
1 | DOW7 | -88.171700 | 32.710800 | 74960.42 | IOP1 | 2022-03-22 17:59:03 | 2022-03-22 23:37:13 |
2 | DOW8 | -88.436500 | 33.262500 | 58545.50 | IOP1 | 2022-03-22 20:02:00 | 2022-03-22 21:08:50 |
3 | COW1 | -88.548200 | 33.606340 | 88443.41 | IOP2 | 2022-03-30 15:52:26 | 2022-03-31 02:18:40 |
4 | DOW7 | -88.608500 | 33.485000 | 74960.42 | IOP2 | 2022-03-30 18:57:33 | 2022-03-31 02:19:07 |
5 | DOW8 | -88.662700 | 33.723800 | 73529.96 | IOP2 | 2022-03-30 21:42:12 | 2022-03-31 02:20:11 |
6 | COW1 | -86.544500 | 32.269600 | 88443.41 | IOP3 | 2022-04-05 12:32:48 | 2022-04-05 17:28:42 |
7 | DOW7 | -86.679100 | 32.428000 | 74960.42 | IOP3 | 2022-04-05 13:01:09 | 2022-04-05 16:24:53 |
8 | DOW8 | -86.430200 | 32.197800 | 58545.50 | IOP3 | 2022-04-05 14:39:27 | 2022-04-05 17:29:50 |
9 | UAHM | -88.495400 | 33.132500 | 50000.00 | IOP1 | 2022-03-22 22:34:17 | 2022-04-13 20:22:14 |
10 | UAHM | -88.712067 | 33.840030 | 99750.00 | IOP2 | 2022-03-30 15:13:12 | 2022-03-31 01:42:02 |
11 | NOXP | -88.495216 | 33.132534 | 74962.00 | IOP2 | 2022-03-30 18:29:28 | 2022-03-31 01:34:18 |
12 | SMARTR1 | -88.345871 | 32.888432 | 98975.00 | IOP1 | 2022-03-22 16:05:24 | 2022-03-22 21:17:49 |
13 | SMARTR2 | -88.570110 | 33.213134 | 81900.00 | IOP1 | 2022-03-22 15:49:30 | 2022-03-22 22:48:37 |
14 | SMARTR2 | -88.484060 | 33.346680 | 82950.00 | IOP2 | 2022-03-30 19:11:36 | 2022-03-31 02:27:34 |
import geopandas as gpd
import shapely.geometry as sgeom
import numpy as np
from cartopy.geodesic import Geodesic
def draw_circle_on_map(df):
gd = Geodesic()
geoms = []
for _, row in df.iterrows():
lon, lat = row['Lon'], row['Lat']
radius = row['Range[m]']
cp = gd.circle(lon=lon, lat=lat, radius=radius)
geoms.append(sgeom.Polygon(cp))
gdf = gpd.GeoDataFrame(df, geometry=geoms)
gdf.crs = "EPSG:4326" # set the CRS
return gdf
gdf = draw_circle_on_map(df)
gdf
Instrument | Lon | Lat | Range[m] | IOP | Start_Time | End_Time | geometry | |
---|---|---|---|---|---|---|---|---|
0 | COW1 | -87.946000 | 32.810980 | 88443.41 | IOP1 | 2022-03-22 17:04:44 | 2022-03-22 23:03:40 | POLYGON ((-87.94600 33.60843, -87.97926 33.607... |
1 | DOW7 | -88.171700 | 32.710800 | 74960.42 | IOP1 | 2022-03-22 17:59:03 | 2022-03-22 23:37:13 | POLYGON ((-88.17170 33.38670, -88.19982 33.386... |
2 | DOW8 | -88.436500 | 33.262500 | 58545.50 | IOP1 | 2022-03-22 20:02:00 | 2022-03-22 21:08:50 | POLYGON ((-88.43650 33.79035, -88.45856 33.790... |
3 | COW1 | -88.548200 | 33.606340 | 88443.41 | IOP2 | 2022-03-30 15:52:26 | 2022-03-31 02:18:40 | POLYGON ((-88.54820 34.40368, -88.58177 34.403... |
4 | DOW7 | -88.608500 | 33.485000 | 74960.42 | IOP2 | 2022-03-30 18:57:33 | 2022-03-31 02:19:07 | POLYGON ((-88.60850 34.16081, -88.63687 34.160... |
5 | DOW8 | -88.662700 | 33.723800 | 73529.96 | IOP2 | 2022-03-30 21:42:12 | 2022-03-31 02:20:11 | POLYGON ((-88.66270 34.38669, -88.69060 34.386... |
6 | COW1 | -86.544500 | 32.269600 | 88443.41 | IOP3 | 2022-04-05 12:32:48 | 2022-04-05 17:28:42 | POLYGON ((-86.54450 33.06712, -86.57755 33.066... |
7 | DOW7 | -86.679100 | 32.428000 | 74960.42 | IOP3 | 2022-04-05 13:01:09 | 2022-04-05 16:24:53 | POLYGON ((-86.67910 33.10393, -86.70713 33.103... |
8 | DOW8 | -86.430200 | 32.197800 | 58545.50 | IOP3 | 2022-04-05 14:39:27 | 2022-04-05 17:29:50 | POLYGON ((-86.43020 32.72574, -86.45200 32.725... |
9 | UAHM | -88.495400 | 33.132500 | 50000.00 | IOP1 | 2022-03-22 22:34:17 | 2022-04-13 20:22:14 | POLYGON ((-88.49540 33.58331, -88.51420 33.583... |
10 | UAHM | -88.712067 | 33.840030 | 99750.00 | IOP2 | 2022-03-30 15:13:12 | 2022-03-31 01:42:02 | POLYGON ((-88.71207 34.73926, -88.75008 34.738... |
11 | NOXP | -88.495216 | 33.132534 | 74962.00 | IOP2 | 2022-03-30 18:29:28 | 2022-03-31 01:34:18 | POLYGON ((-88.49522 33.80840, -88.52347 33.807... |
12 | SMARTR1 | -88.345871 | 32.888432 | 98975.00 | IOP1 | 2022-03-22 16:05:24 | 2022-03-22 21:17:49 | POLYGON ((-88.34587 33.78082, -88.38316 33.780... |
13 | SMARTR2 | -88.570110 | 33.213134 | 81900.00 | IOP1 | 2022-03-22 15:49:30 | 2022-03-22 22:48:37 | POLYGON ((-88.57011 33.95154, -88.60103 33.951... |
14 | SMARTR2 | -88.484060 | 33.346680 | 82950.00 | IOP2 | 2022-03-30 19:11:36 | 2022-03-31 02:27:34 | POLYGON ((-88.48406 34.09453, -88.51543 34.094... |
def draw_circle_on_map_for_nexrad(df):
gd = Geodesic()
geoms = []
for _, row in df.iterrows():
lon, lat = row['lon'], row['lat']
radius = 250e3
cp = gd.circle(lon=lon, lat=lat, radius=radius)
geoms.append(sgeom.Polygon(cp))
gdf = gpd.GeoDataFrame(df, geometry=geoms)
gdf.crs = "EPSG:4326" # set the CRS
return gdf
gsites = draw_circle_on_map_for_nexrad(sites)
def create_plot(switch):
# Define the data based on the switch variable
if switch == 'IOP1':
data = gdf[gdf['IOP'] == 'IOP1']
elif switch == 'IOP2':
data = gdf[gdf['IOP'] == 'IOP2']
elif switch == 'IOP3':
data = gdf[gdf['IOP'] == 'IOP3']
else:
data = gdf
# Define the point plot based on the data
points = data.hvplot.points(x='Lon', y='Lat', geo=True, color='r',
alpha=0.7, coastline=True,
frame_height=800, frame_width=650,
hover_cols=['Instrument', 'Range[m]', 'IOP', 'Start_Time', 'End_Time'])
# Define the circle plot based on the data
circles = gv.Polygons(data=data.geometry).opts(color='gray', fill_alpha=0.2,
xlabel='Lon˚E', ylabel='Lat˚N',
frame_height=800, frame_width=650)
# Define the point plot for the gsites data
points_nex = gsites.hvplot.points(x='lon', y='lat', geo=True, color='k',
alpha=0.7, hover_cols=['ID'],
coastline=True,
tiles='OpenTopoMap',
frame_height=800, frame_width=650)
# Define the circle plot for the gsites data
circles_nex = gv.Polygons(data=gsites.geometry).opts(color='w', fill_alpha=0.2,
xlabel='Lon˚E', ylabel='Lat˚N',
frame_height=800, frame_width=650)
# Overlay the circle plot on top of the point plot
plot = points_nex * circles_nex * points * circles
return plot
create_plot('IOP1')
create_plot('IOP2')
create_plot('IOP3')
create_plot(None)
def create_plot(switch):
# Define the data based on the switch variable
if switch == 'IOP1':
data = gdf[gdf['IOP'] == 'IOP1']
elif switch == 'IOP2':
data = gdf[gdf['IOP'] == 'IOP2']
elif switch == 'IOP3':
data = gdf[gdf['IOP'] == 'IOP3']
else:
data = gdf
# Define the colormap for instrument colors
instrument_colors = {'COW1': 'red', 'DOW7': 'blue', 'DOW8': 'green',
'UAHM': 'orange', 'NOXP': 'purple', 'SMARTR1': 'cyan',
'SMARTR2': 'magenta'}
# Create a color column based on the Instrument column
data['Color'] = data['Instrument'].map(instrument_colors)
# Define the point plot based on the data
points = data.hvplot.points(x='Lon', y='Lat', geo=True, color='Color',
alpha=0.7, coastline=True,
frame_height=800, frame_width=650,
hover_cols=['Instrument', 'Range[m]', 'IOP', 'Start_Time', 'End_Time'])
# Define the circle plot based on the data
circles = gv.Polygons(data=data.geometry).opts(fill_alpha=0.2,
xlabel='Lon˚E', ylabel='Lat˚N',
frame_height=800, frame_width=650)
# Define the point plot for the gsites data
points_nex = gsites.hvplot.points(x='lon', y='lat', geo=True, color='k',
alpha=0.7, hover_cols=['ID'],
coastline=True,
tiles='OpenTopoMap',
frame_height=800, frame_width=650)
# Define the circle plot for the gsites data
circles_nex = gv.Polygons(data=gsites.geometry).opts(color='w', fill_alpha=0.2,
xlabel='Lon˚E', ylabel='Lat˚N',
frame_height=800, frame_width=650)
# Overlay the circle plot on top of the point plot
plot = points_nex * circles_nex * points * circles
return plot
create_plot('IOP2')