Analysis of Antarctic Sea Ice Extension: Annual Maxima and Minima

Analysis of Antarctic Sea Ice Extension: Annual Maxima and Minima#

For an interactive version of this page please visit the Google Colab:
Open in Google Colab
(To open link in new tab press Ctrl + click)

The extent of Antarctic Ice Sheet (AIS) serves as a critical indicator for understanding climate change dynamics and marine ecosystem shifts in one of the Earth’s most remote regions. The extent of Antarctic Ice Sheet is usually a re-analysis product. All the data is available in the OCEAN:ICE backend data tools.

This notebook processes and presents the annual minimum and maximum extent of the AIS.
The tool uses the following products:

Hide code cell source
'''This block of code gets a list of geojsons containing informations about the antarctic ice sheet by year.
The function reduceFun creates a dictionary with the data needed for the following cells of code'''
from functools import reduce
import requests
import json
from ipywidgets import Output, HBox
import warnings

warnings.filterwarnings('ignore')

resp = requests.get('https://geoserver.s4oceanice.eu/geoserver/oceanice/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=oceanice%3AEMODnet_ice_edge_sh_annual&outputFormat=application%2Fjson&srsName=epsg:4326')

iceJson = resp.content
iceData = json.loads(iceJson)

def reduceFun(a, c):
  if c['properties']['year'] not in a.keys():
    a[c['properties']['year']] = {'type': "FeatureCollection", 'features':[]}
  a[c['properties']['year']]['features'].append(c)
  
  return a

iceDict = reduce(reduceFun, iceData['features'], {})

In the subsequent code cell, we calculate and visualize the minimum and maximum areas of the Antarctic ice sheet are calculated and visualized across various years. For each year, polygons representing ice sheet extent are processed and their areas are calculated after ensuring geometries are valid. The resulting minimum and maximum areas are plotted as bars, facilitating a comparative analysis of ice sheet fluctuations over time.

Note: Some of the data may be missing so the values have to be considered as minimum limits.

Hide code cell source
import geopandas as gpd
from pyproj import Geod, Proj
from shapely.geometry import shape
import matplotlib.pyplot as plt

min_areas = {}
max_areas = {}

geod = Geod('+a=6378137 +f=0.0033528106647475126')

# Loop through each year in the iceDict
for year, data in iceDict.items():
    min_polygons = []
    max_polygons = []

    # Separate geometries into minima and maxima
    for feature in data['features']:
        geom = shape(feature['geometry'])
        minmax = feature['properties']['minmax']

        if minmax == 0: 
            max_polygons.append(geom)
        else:
            min_polygons.append(geom)

    # Create GeoDataFrames for minima and maxima
    min_gdf = gpd.GeoDataFrame(geometry=min_polygons, crs="EPSG:4326")
    max_gdf = gpd.GeoDataFrame(geometry=max_polygons, crs="EPSG:4326")

    # Reproject to Antarctic Polar Stereographic (EPSG:3031)
    min_gdf = min_gdf.to_crs("EPSG:3031")
    max_gdf = max_gdf.to_crs("EPSG:3031")

    # Calculate area in millions of square kilometers for minima and maxima
    min_gdf['area_km2'] = min_gdf['geometry'].area / 10**12
    max_gdf['area_km2'] = max_gdf['geometry'].area / 10**12

    # Sum up the areas for each
    total_min_area = min_gdf['area_km2'].sum()
    total_max_area = max_gdf['area_km2'].sum()

    max_areas[year] = total_max_area
    min_areas[year] = total_min_area

# Sort the years
sorted_years = sorted(min_areas.keys())

# # Prepare data for plotting
min_values = [min_areas[year] for year in sorted_years]
max_values = [max_areas[year] for year in sorted_years]

# Plot the data
plt.figure(figsize=(10, 6))
plt.bar(sorted_years, max_values, label='Max Ice Sheet Area', color='red')
plt.bar(sorted_years, min_values, label='Min Ice Sheet Area', color='blue')
plt.xlabel('Year')
plt.ylabel('Area (millions of km²)')
plt.ticklabel_format(axis='y', style='plain')
plt.title('Antarctic Ice Sheet Area Over Years')
plt.legend()
plt.grid(True)
plt.show()
../../_images/290cee562dcbb418f2a65a3a200c9fdb1ed721e246b6bfd11e4c0674f11929a0.png

The subsequent code cell generates a map using the ipyleaflet library to visualize the Antarctic ice sheet extent for different years. The map employs an Antarctic basemap and allows users to observe the ice sheet’s minimum and maximum extents, shown in blue and red, respectively.

Hide code cell source
from ipyleaflet import Map, Marker, basemaps, WMSLayer, projections, GeoJSON, WidgetControl, LegendControl
from ipywidgets import interact, SelectionSlider, VBox, Text, Layout

'''This function is used to create colored layers, it will be used in the next block of code'''
def colorFun(feature):
  if feature['properties']['minmax'] == 0:
    return {
        'color': 'black',
        'fillColor': 'red'
    }
  else:
    return {
        'color': 'black',
        'fillColor': 'blue'
    }

years = list(iceDict.keys())

years.sort()

actualYear = years[-1]

m3 = Map(basemap=basemaps.Esri.AntarcticBasemap, crs=projections.EPSG3031.ESRIBasemap, center=(-90, 0), zoom=2)

legend = LegendControl({"Min Ice Sheet":"blue", "Max Ice Sheet":"red"}, name="", position="topleft")
m3.add_control(legend)

time_descr = Text(value= 'Year: ' + actualYear , description='', layout=Layout(width='180px'), disabled=True)
# add to m3

EP = dict(
    name='EPSG:3031',
    custom=True,
    proj4def="""+proj=stere +lat_0=-90 +lat_ts=-71 +lon_0=0 +k=1
        +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs""",
    bounds=[[-3174450,-2816050],[2867175,2406325]]
)

geo_json = GeoJSON(
    data = iceDict[actualYear],
    style={
        'opacity': 1, 'fillOpacity': 0.5, 'weight': 1
    },
    style_callback=colorFun
)

m3.add_layer(geo_json)

VBox([HBox([time_descr]), VBox([m3])])

Additional resources#

The Python libraries that have been used in this notebook are: