Visualization
Contents
Visualization#
author: Hamid Ali Syed
email: hamidsyed37[at]gmail[dot]com
Import packages#
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
Read the data#
df = pd.read_csv("IMD_Radar_Sites_2022.csv").drop(["Unnamed: 0", "State"], axis=1)
counts = df.groupby('Band').agg(count=('Band', 'size'))
display(counts)
# Print the total number of radars
total_radars = counts.sum()
print(f"Total number of radars: {total_radars[0]}")
count | |
---|---|
Band | |
C | 4 |
S | 22 |
X | 7 |
Total number of radars: 33
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['Longitude'], row['Latitude']
if row['Band'] == "X":
radius=100e3
else:
radius=250e3
cp = gd.circle(lon=lon, lat=lat, radius=radius)
geoms.append(sgeom.Polygon(cp))
gdf = gpd.GeoDataFrame(df, geometry=geoms)
return gdf
gdf = draw_circle_on_map(df)
gdf
Site | Latitude | Longitude | Band | geometry | |
---|---|---|---|---|---|
0 | Srinagar | 34.083656 | 74.797371 | X | POLYGON ((74.79737 34.98511, 74.75915 34.98455... |
1 | Jammu | 32.926600 | 74.857000 | X | POLYGON ((74.85700 33.82822, 74.81930 33.82767... |
2 | Jot | 32.486800 | 76.059300 | X | POLYGON ((76.05930 33.38849, 76.02179 33.38793... |
3 | Kufri | 31.097800 | 77.267800 | X | POLYGON ((77.26780 31.99968, 77.23087 31.99913... |
4 | Murari | 30.789800 | 78.917850 | X | POLYGON ((78.91785 31.69173, 78.88104 31.69117... |
5 | Surkandaji | 30.411400 | 78.288500 | X | POLYGON ((78.28850 31.31338, 78.25184 31.31283... |
6 | Patiala | 30.339800 | 76.386900 | S | POLYGON ((76.38690 32.59454, 76.29399 32.59313... |
7 | Mukteshwar | 29.460400 | 79.655800 | X | POLYGON ((79.65580 30.36251, 79.61950 30.36196... |
8 | Palam | 28.590100 | 77.088800 | S | POLYGON ((77.08880 30.84545, 76.99762 30.84404... |
9 | Delhi | 28.563200 | 77.191200 | C | POLYGON ((77.19120 30.81855, 77.10004 30.81715... |
10 | Mohanbari | 27.472800 | 94.912000 | S | POLYGON ((94.91200 29.72852, 94.82184 29.72712... |
11 | Jaipur | 26.912400 | 75.787300 | C | POLYGON ((75.78730 29.16831, 75.69764 29.16690... |
12 | Lucknow | 26.846700 | 80.946200 | S | POLYGON ((80.94620 29.10263, 80.85659 29.10123... |
13 | Patna | 25.594100 | 85.137600 | S | POLYGON ((85.13760 27.85043, 85.04904 27.84903... |
14 | Sohra | 25.270200 | 91.732300 | S | POLYGON ((91.73230 27.52664, 91.64400 27.52523... |
15 | Agartala | 23.831500 | 91.286800 | S | POLYGON ((91.28680 26.08838, 91.19961 26.08698... |
16 | Bhopal | 23.259900 | 77.412600 | S | POLYGON ((77.41260 25.51695, 77.32583 25.51555... |
17 | Bhuj | 23.242000 | 69.666900 | S | POLYGON ((69.66690 25.49906, 69.58014 25.49766... |
18 | Kolkata | 22.572600 | 88.363900 | S | POLYGON ((88.36390 24.82985, 88.27761 24.82846... |
19 | Nagpur | 21.145800 | 79.088200 | S | POLYGON ((79.08820 23.40346, 79.00287 23.40206... |
20 | Paradip | 20.316600 | 86.611400 | S | POLYGON ((86.61140 22.57449, 86.52658 22.57309... |
21 | Veravali | 19.734300 | 72.876300 | C | POLYGON ((72.87630 21.99234, 72.79183 21.99095... |
22 | Gopalpur | 19.264700 | 84.862000 | S | POLYGON ((84.86200 21.52287, 84.77781 21.52147... |
23 | Mumbai | 19.076000 | 72.877700 | S | POLYGON ((72.87770 21.33421, 72.79362 21.33282... |
24 | Visakhapatnam | 17.686800 | 83.218500 | S | POLYGON ((83.21850 19.94536, 83.13518 19.94397... |
25 | Hyderabad | 17.385000 | 78.486700 | S | POLYGON ((78.48670 19.64363, 78.40353 19.64224... |
26 | Machilipatnam | 16.190500 | 81.136200 | S | POLYGON ((81.13620 18.44941, 81.05363 18.44802... |
27 | Panaji | 15.490900 | 73.827800 | S | POLYGON ((73.82780 17.74996, 73.74555 17.74857... |
28 | Sriharikota | 13.725900 | 80.226600 | S | POLYGON ((80.22660 15.98533, 80.14511 15.98394... |
29 | Chennai | 13.082700 | 80.270700 | S | POLYGON ((80.27070 15.34225, 80.18947 15.34086... |
30 | Karaikal | 10.925400 | 79.838000 | S | POLYGON ((79.83800 13.18533, 79.75754 13.18394... |
31 | Kochi | 9.931200 | 76.267300 | S | POLYGON ((76.26730 12.19129, 76.18715 12.18990... |
32 | Thiruvananthapuram | 8.524100 | 76.936600 | C | POLYGON ((76.93660 10.78438, 76.85684 10.78300... |
points = df.hvplot.points(x='Longitude', y='Latitude', geo=True, color='Band',
alpha=0.7, coastline = True,
xlim=(df.Longitude.min()-5, df.Longitude.max()+3),
ylim=(df.Latitude.min()-3, df.Latitude.max()+3),
tiles='OpenTopoMap', frame_height=800, frame_width=650, hover_cols=['Site', 'Band'], value_label='Count')
# Create the circle plot
circles = gv.Polygons(data=gdf.geometry,).opts(color = "gray", fill_alpha=0.2, xlabel = "LongitudeËšE", ylabel = "LatitudeËšN",
frame_height=800, frame_width=650)
# Overlay the circle plot on top of the point plot
plot = points * circles
# Show the plot
display(plot)
import urllib.request
url = "https://raw.githubusercontent.com/syedhamidali/test_scripts/master/map_features.py"
urllib.request.urlretrieve(url, "map_features.py")
import map_features as mf
!git clone https://github.com/aman1chaudhary/India-Shapefiles.git
fatal: destination path 'India-Shapefiles' already exists and is not an empty directory.
india = gpd.read_file("India-Shapefiles/India Boundary/")
states = gpd.read_file("India-Shapefiles/India States Boundary/")
fig = plt.figure(figsize = [10,12], dpi=300)
ax = plt.axes(projection=ccrs.PlateCarree(), frameon=False)
BAND = ["X", "C", "S"]
col = ['red', '#4B04E2', '#58D68D']
# Count occurrences of each 'Band' value
band_counts = df['Band'].value_counts().to_dict()
for band, c in zip(BAND, col):
# Get the count for the current 'Band' value
count = band_counts[band]
# Create the label for the legend
label = f"{band} - Band ({count})"
df[df['Band']==band].plot.scatter(x='Longitude', y='Latitude', ax=ax, c=c, s=10, label=label, zorder=10)
ax.add_geometries(gdf[gdf.Band == band].geometry, crs=ccrs.PlateCarree(),
alpha=0.4, edgecolor="k", facecolor=c)
# Add text labels to each point
for i, txt in enumerate(df['Site']):
x = df['Longitude'][i]
y = df['Latitude'][i]
if txt == "Delhi":
y -= 0.5
dx = 0.01 * (max(df['Longitude']) - min(df['Longitude']))
dy = 0.01 * (max(df['Latitude']) - min(df['Latitude']))
ax.text(x + dx, y + dy, txt, fontsize=8)
india.plot(ax=ax, ec = "k", fc = "none", lw=0.5, alpha = 0.6, )
states.plot(ax=ax, ec ="k", fc = "none", lw=0.2, alpha = 0.5, ls=":")
ax.legend(title = f"Total DWRs: {counts.sum()[0]}", shadow = True)
mf.map_features(ax=ax, ocean=True, borders=False, states=False, land=True)
ax.minorticks_on()
ax.tick_params(axis='both', which='major', labelsize=12, width=0.5, color='#555555', length=8, direction='out')
ax.tick_params(axis='both', which='minor', labelsize=10, width=0.5, color='#555555', length=4, direction='out')
ax.set_xticks(np.arange(df.Longitude.min(), df.Longitude.max()+1, 5))
ax.set_yticks(np.arange(df.Latitude.min(), df.Latitude.max()+1, 5))
ax.set_xlabel("LongitudeËšE")
ax.set_ylabel("LatitudeËšN")
ax.set_extent([65, 98, 5, 37])
ax.set_autoscale_on(True)
plt.show()
import matplotlib.pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
import urllib.request
from PIL import Image
import io
url = "https://mausam.imd.gov.in/imd_latest/contents/map-marker-icon-png-green.png"
# Open the URL and read the image data into a bytes object
with urllib.request.urlopen(url) as response:
img_data = response.read()
# Create a PIL Image object from the image data
ma_img = Image.open(io.BytesIO(img_data))
# Convert the PIL Image to a NumPy array
marker_img = np.array(ma_img)
# Create a function to create an OffsetImage object for each marker
def make_marker(lon, lat):
# Set the size of the marker image
size = 0.05
# Convert the coordinates to the map's coordinate system
x, y = ax.projection.transform_point(lon, lat, ccrs.PlateCarree())[:2]
# Create the OffsetImage object
img = OffsetImage(marker_img, zoom=size)
img.image.axes = ax
ab = AnnotationBbox(img, (x,y), frameon=False)
ax.add_artist(ab)
BAND = ["X", "C", "S"]
col = ['red', '#4B04E2', '#04E2D8']
# Create the map figure
fig = plt.figure(figsize=[10, 12], dpi=300)
ax = plt.axes(projection=ccrs.PlateCarree(), frameon=False)
# Plot the data points
for band, c in zip(BAND, col):
count = band_counts[band]
label = f"{band} - Band ({count})"
df[df['Band'] == band].plot.scatter(x='Longitude', y='Latitude',
ax=ax, c=c, s=10, label=label)
ax.add_geometries(gdf[gdf.Band == band].geometry, crs=ccrs.PlateCarree(),
alpha=0.4, edgecolor="k", facecolor=c)
# Add the custom marker to each data point
for i, row in df.iterrows():
make_marker(row['Longitude'], row['Latitude'])
# Add text labels to each point
for i, txt in enumerate(df['Site']):
x = df['Longitude'][i]
y = df['Latitude'][i]
if txt == "Delhi":
y -= 0.5
dx = 0.01 * (max(df['Longitude']) - min(df['Longitude']))
dy = 0.01 * (max(df['Latitude']) - min(df['Latitude']))
ax.text(x + dx, y + dy, txt, fontsize=8)
# Add the map features and labels
india.plot(ax=ax, ec="k", fc="none", lw=0.5, alpha=0.6)
states.plot(ax=ax, ec="k", fc="none", lw=0.2, alpha=0.5, ls=":")
mf.map_features(ax=ax, ocean=True, borders=False, states=False, land=True)
ax.minorticks_on()
ax.tick_params(axis='both', which='major', labelsize=12, width=0.5,
color='#555555', length=8, direction='out')
ax.tick_params(axis='both', which='minor', labelsize=10, width=0.5,
color='#555555', length=4, direction='out')
ax.set_xticks(np.arange(df.Longitude.min(), df.Longitude.max()+1, 5))
ax.set_yticks(np.arange(df.Latitude.min(), df.Latitude.max()+1, 5))
ax.set_xlabel("LongitudeËšE")
ax.set_ylabel("LatitudeËšN")
ax.set_extent([65, 98, 5, 37])
ax.set_autoscale_on(True)
# Show the legend and the plot
ax.legend(title=f"Total DWRs: {counts.sum()[0]}", shadow=True)
plt.show()
import ipyleaflet as ipyl
# Create the polygon layer
gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.Longitude, df.Latitude))
polygons_layer = ipyl.GeoJSON(
data=gdf.__geo_interface__,
style={'color': 'gray', 'fillOpacity': 0.2})
import folium
from folium.plugins import MarkerCluster
# Set xlim and ylim
xlim = (df.Longitude.min() - 5, df.Longitude.max() + 3)
ylim = (df.Latitude.min() - 3, df.Latitude.max() + 3)
# Create the folium map object
m = folium.Map(location=[df['Latitude'].mean(), df['Longitude'].mean()], zoom_start=5, tiles='openstreetmap',xlim=xlim, ylim=ylim)
# Add markers to the map
marker_cluster = MarkerCluster().add_to(m)
for idx, row in df.iterrows():
folium.Marker([row['Latitude'], row['Longitude']],
popup=f"Site: {row['Site']}, Band: {row['Band']}",
icon=folium.Icon(color=row['Band'])).add_to(marker_cluster)
# Add circles to the map
for idx, row in gdf.iterrows():
if row['Band'] == 'X':
radius = 100e3
else:
radius = 250e3
folium.Circle(location=[row['geometry'].y, row['geometry'].x],
radius=radius,
fill=True,
fill_opacity=0.2,
color='gray').add_to(m)
# Display the map
m
Make this Notebook Trusted to load map: File -> Trust Notebook