seaborn: a brief introduction

Author

Marie-Hélène Burle

seaborn, at its core, is a statistical visualization library for tabular data[1]. It is based on matplotlib, but its higher-level, declarative, and easy interface makes it ideal for exploratory data analysis (EDA). It comes with demo datasets and statistical tools.

Getting data

seaborn comes with a number of datasets used in its documentation. They are convenient to play with the library. In this section however, we use snow survey data for the province of British Columbia (Canada). I am interested in assessing whether global warming is causing a decrease in the snowpack height in this part of the world.

The data is tabular and stored in a CSV file. We read it into a Polars DataFrame:

import polars as pl

file_path = "/project/def-sponsor00/data/allmss_archive.csv"

Troubleshooting data reading

As we saw earlier, you read tabular data in a Polars DataFrame with:

df = pl.read_csv(file_path)

However, here, we get the following error:

ComputeError: could not parse `35.0` as dtype `i64` at column ' Snow Depth cm' (column number 5)

With, conveniently, the following suggestions:

You might want to try:
- increasing `infer_schema_length` (e.g. `infer_schema_length=10000`),
- specifying correct dtype with the `schema_overrides` argument
- setting `ignore_errors` to `True`,
- adding `35.0` to the `null_values` list.n

If you want to be sure to read the data without error, you can use ignore_errors=True, but this will drop the problematic rows and you will loose data. This is the solution of last resort.

A better solution here is to set the schema for the problematic variable manually:

df = pl.read_csv(file_path, schema_overrides={" Snow Depth cm": pl.Float64})

But oops. We now get the following error:

ComputeError: could not parse `760.0` as dtype `i64` at column ' Water Equiv. mm' (column number 6)

Your turn:

Fix the new problem to read in the data.

Data exploration and transformation

Here is our DataFrame:

df
shape: (60_265, 10)
Snow Course Name Number Elev. metres Date of Survey Snow Depth cm Water Equiv. mm Survey Code Snow Line Elev. m Density % Survey Period
str str i64 str f64 f64 str str i64 str
"YELLOWHEAD" "1A01" 1860 "1951/03/30" 168.0 528.0 null null 31 "01-Apr"
"YELLOWHEAD" "1A01" 1860 "1951/04/30" 147.0 485.0 null null 33 "01-May"
"YELLOWHEAD" "1A01" 1860 "1951/05/19" 89.0 320.0 null null 36 "15-May"
"YELLOWHEAD" "1A01" 1860 "1952/04/30" 157.0 523.0 null null 33 "01-May"
"YELLOWHEAD" "1A01" 1860 "1952/05/19" 79.0 264.0 null null 33 "15-May"
"STANLEY CREEK" "4E03" 930 "1985/05/16" 83.0 307.0 null null 37 "15-May"
"STANLEY CREEK" "4E03" 930 "1986/03/02" 142.0 320.0 null null 23 "01-Mar"
"STANLEY CREEK" "4E03" 930 "1986/04/01" 135.0 365.0 "PROBLEM" null 27 "01-Apr"
"STANLEY CREEK" "4E03" 930 "1986/05/01" 121.0 400.0 "PROBLEM" null 33 "01-May"
"STANLEY CREEK" "4E03" 930 "1986/05/15" 83.0 285.0 null null 34 "15-May"

First cleaning

Let’s create a cleaned DataFrame with relevant columns, the date into a proper format, etc.:

snow_data = df.select(
    pl.col("Snow Course Name").str.to_titlecase().alias("station"),
    pl.col(" Elev. metres").alias("elevation"),
    pl.col(" Date of Survey").str.to_date("%Y/%m/%d").alias("date"),
    pl.col(" Snow Depth cm").alias("snow"),
    pl.col(" Water Equiv. mm").alias("water")
)

snow_data
shape: (60_265, 5)
station elevation date snow water
str i64 date f64 f64
"Yellowhead" 1860 1951-03-30 168.0 528.0
"Yellowhead" 1860 1951-04-30 147.0 485.0
"Yellowhead" 1860 1951-05-19 89.0 320.0
"Yellowhead" 1860 1952-04-30 157.0 523.0
"Yellowhead" 1860 1952-05-19 79.0 264.0
"Stanley Creek" 930 1985-05-16 83.0 307.0
"Stanley Creek" 930 1986-03-02 142.0 320.0
"Stanley Creek" 930 1986-04-01 135.0 365.0
"Stanley Creek" 930 1986-05-01 121.0 400.0
"Stanley Creek" 930 1986-05-15 83.0 285.0

We can explore the data a bit:

print(snow_data.columns)
['station', 'elevation', 'date', 'snow', 'water']
snow_data.glimpse()
Rows: 60265
Columns: 5
$ station    <str> 'Yellowhead', 'Yellowhead', 'Yellowhead', 'Yellowhead', 'Yellowhead', 'Yellowhead', 'Yellowhead', 'Yellowhead', 'Yellowhead', 'Yellowhead'
$ elevation  <i64> 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860
$ date      <date> 1951-03-30, 1951-04-30, 1951-05-19, 1952-04-30, 1952-05-19, 1953-04-01, 1953-05-01, 1953-05-15, 1954-04-05, 1954-04-29
$ snow       <f64> 168.0, 147.0, 89.0, 157.0, 79.0, 140.0, 130.0, 91.0, 193.0, 198.0
$ water      <f64> 528.0, 485.0, 320.0, 523.0, 264.0, 404.0, 455.0, 297.0, 564.0, 577.0
snow_data.describe()
shape: (9, 6)
statistic station elevation date snow water
str str f64 str f64 f64
"count" "60265" 60265.0 "60265" 59806.0 59801.0
"null_count" "0" 0.0 "0" 459.0 464.0
"mean" null 1363.41369 "1989-10-21 01:30:49.371940" 118.480019 428.141503
"std" null 402.853802 null 94.081751 415.776042
"min" "Aberdeen Lake" 0.0 "1935-03-22" 0.0 0.0
"25%" null 1100.0 "1976-04-28" 52.0 136.0
"50%" null 1400.0 "1989-01-01" 98.0 300.0
"75%" null 1660.0 "2004-02-25" 165.0 599.0
"max" "Yellowhead" 2230.0 "2026-02-04" 806.0 3845.0
n_stations = snow_data.select(pl.col("station")).n_unique()
print(f"There are {n_stations} stations.")
There are 364 stations.
list_stations = snow_data.get_column("station").unique().to_list()
print(list_stations)
['Lac Le Jeune Upper', 'Toba River', 'Gnawed Mountain', 'Callaghan Creek', 'Sandon', 'Whistler Mountain', 'Nahatlatch River', 'Meadow Mountain', 'Kaza Lake', 'Kluachesi Lake', 'Shovelnose Mountain', 'Mount Sheba', 'Haddo Lake', 'Oyama Lake', 'Lyford Mountain', 'North Clemina Creek', 'Canoe River', 'Purcell', 'Ware (Lower)', 'Margaret Lake', 'Tatlayoko Lake', 'Porcupine Ridge', 'Wedeene River', 'Ningunsaw Pass', 'Park Mountain', 'Kwadacha River', 'Steelhead', 'Kemess Creek Upper', 'Iskut', 'Tyaughton Creek (North)', 'Sunday Summit', 'Vermilion River No.4', 'Blue River Town', 'Islaht Lake', 'Pass Lake', 'Upper Thelwood Lake', 'Upper Elk River', 'Tsaydaychi Lake', 'Monashee Pass', 'Tenquille Lake', 'Prince George Airport', 'Bullhead Mountain', 'Mount Timothy', 'Boston Bar Creek (Upper)', 'Kostal Lake', 'New Glacier', 'Cook Forks', 'Sumallo River West', 'Deadman River', 'Schaft Creek', 'Azure River', 'Forbidden Plateau', 'Cornwall Hills', 'Granite Mountain', 'Mckendrick Creek', 'Silver Star Mountain', 'Tennent Lake', 'Hollyburn', 'Sno-Bird Lake', 'Mount Copeland', 'Wahleach Lake', 'Upper Stikine', 'Mount Abbot', 'Blackhawk', 'Fernie East', 'Esperon Creek Middle', 'Morfee Mountain', 'Esperon Creek Lower', 'Upper Quinsam', 'Fort St. John Airport', 'Graystoke Lake', 'Beatton River', 'Bralorne (Upper)', 'Postill Lake', 'Pavilion', 'Enderby', 'Summerland Reservoir', 'Fidelity Mountain', 'Wolf River Upper', 'Red Chris Mine Lower', 'Mcgillivray Pass', 'Smithers', 'Morrissey Ridge', 'Knudsen Lake', 'Copper Mountain', 'Gray Creek Upper', 'Arrow Creek', 'Sikanni Lake', 'Mount Assiniboine', 'Dease Lake', 'Wedeene River South', 'Pondosy Lake', 'Palisade Lake', 'Greyback Reservoir', 'Nickel Plate', 'Esperon Creek Upper', 'Blackwater Creek', 'Highland Valley', 'Wade Lake', 'Anglemont', 'Tachek Creek', 'Mcbride Lower', 'Sumallo River', 'Mount Revelstoke', 'Machmell River', 'Mcleod Lake', 'Aberdeen Lake', 'Mcbride Middle', 'Lost Horse Mountain', 'Invermere', 'Upper Stave River', 'Keystone Creek', 'Kimberley (Middle)Vor', 'Loch Lomond', 'Coquitlam Lake', 'Moyie Mountain', 'Yellowhead', 'Blackwater Lookout', 'Terrace Airport', 'Mount Kobau', 'Fernie (Ne)', 'Ferguson', 'Braden River', 'Bear Creek Reservoir', 'Humamilt Lake', 'Lightning Lake', 'Harlow Creek', 'Burns Lake', 'Bear Pass', 'Char Creek', 'Mount Wells', 'Pennask Creek', 'Monkman Creek', 'Edwards Lake', 'Watam Lake', 'Adams River', 'Alligator Meadows', 'Bonaparte Lake', 'Holmes River', 'Hamilton Hill', 'Dog Mountain', 'Telegraph Creek', 'Penfold Creek', 'Mcqueen Lake', 'Johanson Lake', 'Vermont Creek', 'Isintok Lake', 'Downie Slide Upper', 'Floe Lake', 'Mount Templeman', 'Lost Ledge', 'Atlin Lake', 'Fernie Ridge', 'Wolf River Middle', 'Germansen Lower', 'Bluejoint Mountain', 'Yanks Peak', 'Hourglass', 'Record Mountain', 'Mcbride Upper', 'Missezula Mountain', 'Trout River', 'Heather Mountain', 'Revolution Creek', 'Klesilkwa', 'Trygve Lake', 'Tiedemann Glacier', 'Spahomin', 'Mackenzie Airport', 'Philip Lake', 'Link Lake', 'Trout Creek West', 'Fort St. James', 'Tripp Meadows', 'Bouleau Lake', 'East Creek', 'Red Chris Mine Upper', 'Missinka River', 'Carrs Landing (Upper)', 'Triumph Creek', 'Stanley Creek', 'Bugaboo Creek', 'Great Bear', 'Log Cabin', 'Trapping Creek', 'Fish Lake', 'Granduc Mine', 'Dome Mountain', 'Black Mountain', 'Heather Mountain Upper', 'Tahtsa Lake', 'Vermilion River No.2', 'Conant Lake', 'Beaverfoot', 'Grayling River', 'Elk River', 'Rabbit River', 'Lytton', 'Fernie', 'Hansard', 'Bridge Glacier Lower', 'Carmi', 'Tashme', 'Bella Coola', 'Torpy River', 'Mount Penrose', 'Kimberley (Lower) Vor', 'Farron', 'Brookmere', 'Forfar Creek (Upper)', 'Shalalth', 'Nelson', 'Summit Lake', 'Trophy Mountain', 'Bush River', 'Knouff Lake', 'Stave Lake', 'Pink Mountain', 'Sproat Lake', 'Deadwood River', 'Big Creek', 'Tahltan Lake', 'Trout Creek', 'Disappointment Lake', 'Garibaldi Lake', 'June Lake', 'Mount Joffre', 'Whiterocks Mountain', 'Harry Lake', 'Downton Lake Upper', 'Kinaskan Lake', 'Sullivan Mine', 'Vermilion River No. 3', 'Mount Saint Anne', 'Mcculloch', 'Caverhill Lake New', 'Germansen Upper', 'Mission Creek', 'Alouette Lake', 'Fredrickson Lake', 'Trapping Creek (Upper)', 'Labour Day Lake', 'Whatshan Upper', 'Longworth Lower', 'Tranquille Lake', 'Ottomite', 'Trapping Creek (Lower)', 'Kidprice Lake', 'Cassiar', 'Mount Roosevelt', 'Grouse Mountain', 'Whatshan Lower', 'Lu Lake', 'Puntzi Mountain', 'Hedrick Lake', 'Middle River', 'Kemess Creek Lower', 'Mica Creek', 'Forrest Kerr Creek', 'Mount Seymour', 'Jade City', 'Mount Cronin', 'Bouleau Creek', 'New Tashme', 'Marble Canyon', 'Nazko', 'Chapman Creek', 'Lac Le Jeune Lower', 'Portage Mountain', 'Blackwall Peak', 'Pine Pass', 'Ipec Lake', 'Green Mountain', 'Nostetuko River', 'Burman Lake', 'Powell River', 'Mount Albreda', 'Downie Site 8', 'Kirbyville Lake', 'Equity Mine', 'Eaglenest Creek', 'Longworth Upper', 'Memory Lake', 'Hope', 'Pacific Lake', 'Sinclair Pass', 'Big White Mountain', 'Newcastle Ridge', 'Pavilion Mtn.', 'Horsefly Mountain', 'Wolf River Lower', 'Precipice', 'Tumeka Creek', 'Chapman Lake', 'Sunbeam Lake', 'Ware (Upper)', 'Duncan Lake No. 2', 'Nutli Lake', 'Kimberley', 'Skins Lake', 'Goldstream', 'Duncan Lake', 'Powell River Upper', 'Boston Bar Creek (Lower)', 'Revelstoke', 'Vermilion River No.5', 'Field', 'Frog River', 'Sukunka River', 'Bralorne', 'Narrow Lake', 'Dickson Lake', 'Gerrard', 'Wonowon', 'Snippaker Creek', 'Vaseux Creek', 'Cypress Lake', 'Barnes Creek', 'Carrs Landing (Lower)', 'Orchid Lake', 'Blue River', 'Hudson Bay Mountain', 'Lady Laurier Lake', 'Mount Swannell', 'French Snowshoe', 'Tutizzi Lake', 'Toad River', 'Fort Nelson Airport', 'Pearson Creek', 'Macdonald Lake', 'Glacier', 'Wolverine Creek', 'Bigmouth Creek', 'Downie Slide Lower', 'Postill Lake Upper', 'Mackenzie Airport Manual Snow Course (2003)', 'Nechako', 'Mount Cook', 'Duffey Lake', 'Old Glory Mountain', 'Boundary', 'Barkerville', 'Thunder Creek', 'Mount Stearns', 'Fish Lake No. 2', 'Gray Creek Lower', 'Mount Cokely', 'Bird Creek', 'Kinbasket Lake', 'Pulpit Lake', 'Bullmoose Creek', 'Kimberley (Upper) Vor', 'Bluff Creek', 'Boss Mountain Mine', 'Whitesail Lake', 'St. Leon Creek', 'Powell River Lower', 'Bowron Lake', 'Diamond Head', 'Kicking Horse', 'Vermilion River No.1', 'Brenda Mine', 'Koch Creek', 'Burwell Lake']

Stations selection

Let’s select subsets of snow pillow stations located in the Southern Coastal Mountains of British Columbia. They exclude stations in the Interior (Okanagan, Kamloops, Kootenays, Cariboo, Rockies, Columbias) and Northern BC. This is where a decrease in snowpack due to global warming is the most likely to be detectable since the temperatures are not very cold and a few degrees of warming is enough to go from snow to rain.

I used Gemini 3 to split the list of stations into mountain ranges. This was very convenient since the data doesn’t include coordinates (that would have allowed to filter by latitude and longitude) nor information about the location of the stations.

# Vancouver Island Ranges:
island_stations = [
    "Burman Lake", "Dickson Lake", "East Creek", "Forbidden Plateau", "Green Mountain",
    "Heather Mountain", "Heather Mountain Upper", "June Lake", "Labour Day Lake",
    "Loch Lomond", "Lyford Mountain", "Mount Cokely", "Mount Wells", "Newcastle Ridge",
    "Sproat Lake", "Tennent Lake", "Upper Quinsam", "Upper Thelwood Lake",
    "Wolf River Lower", "Wolf River Middle", "Wolf River Upper"
]

# Lower Mainland & Fraser Valley:
vancouver_stations = [
    "Alouette Lake", "Black Mountain (Cypress Provincial Park)", "Burwell Lake (North Shore)",
    "Coquitlam Lake", "Dog Mountain (Mount Seymour)", "Grouse Mountain", "Hollyburn", "Hope",
    "Mount Saint Anne (Sunshine Coast/Sechelt)", "Mount Seymour",
    "Orchid Lake (Stave/Lower Mainland)", "Palisade Lake (Capilano Watershed)",
    "Stave Lake", "Steelhead", "Upper Stave River", "Wahleach Lake"
]

# Sea-to-Sky, Garibaldi & Bridge River:
s2s_stations = [
    "Bralorne", "Bralorne (Upper)", "Bridge Glacier Lower", "Callaghan Creek", "Diamond Head",
    "Downton Lake Upper", "Duffey Lake", "Garibaldi Lake", "McGillivray Pass", "Mount Cook",
    "Mount Penrose", "Mount Sheba", "Powell River", "Powell River Lower", "Powell River Upper",
    "Shalalth", "Shovelnose Mountain", "Tenquille Lake", "Toba River",
    "Tyaughton Creek (North)", "Whistler Mountain"
]

# Cascades & Coquihalla (Southern Border Ranges):
cascades_stations = [
    "Blackwall Peak", "Boston Bar Creek (Lower)", "Boston Bar Creek (Upper)", "Great Bear",
    "Klesilkwa", "Lightning Lake", "Nahatlatch River", "New Tashme", "Sumallo River",
    "Sumallo River West", "Sunday Summit", "Tashme"
]

Now we can filter the data for all these stations:

selected_data = snow_data.filter(
    pl.col("station").is_in(
        island_stations + vancouver_stations + s2s_stations + cascades_stations
    )
).with_columns(
    pl.when(pl.col("station").is_in(island_stations)).then(pl.lit("Vancouver Island"))
    .when(pl.col("station").is_in(vancouver_stations)).then(pl.lit("Lower Mainland"))
    .when(pl.col("station").is_in(s2s_stations)).then(pl.lit("Sea to Sky"))
    .otherwise(pl.lit("Cascades"))
    .alias("range")
)

Convert to seasons

Snow pillow data go from October 1st of one year to September 30th of the following year. Let’s add a season column:

season_data = selected_data.with_columns(
    pl.col("date").dt.offset_by("3mo").dt.year().alias("season")
)

season_data
shape: (8_867, 7)
station elevation date snow water range season
str i64 date f64 f64 str i32
"Mount Wells" 1490 1952-02-29 127.0 358.0 "Vancouver Island" 1952
"Mount Wells" 1490 1953-02-26 127.0 371.0 "Vancouver Island" 1953
"Mount Wells" 1490 1953-04-02 117.0 376.0 "Vancouver Island" 1953
"Mount Wells" 1490 1953-05-06 122.0 411.0 "Vancouver Island" 1953
"Mount Wells" 1490 1954-03-02 185.0 577.0 "Vancouver Island" 1954
"Mount Sheba" 1490 2022-12-30 112.0 301.0 "Sea to Sky" 2023
"Mount Sheba" 1490 2023-02-01 null null "Sea to Sky" 2023
"Mount Sheba" 1490 2023-02-28 225.0 715.0 "Sea to Sky" 2023
"Mount Sheba" 1490 2023-03-30 206.0 794.0 "Sea to Sky" 2023
"Mount Sheba" 1490 2023-04-28 208.0 853.0 "Sea to Sky" 2023

Select balanced panel

Our data is in long format. It is the format we want for plotting and analyses. The wide format has use cases too. For instance, it allows to easily see whether data was collected for all stations at all times.

polars.DataFrame.pivot turns a long-format DataFrame to a wide-format one:

stations_years = season_data.pivot(
    "season",
    index="station",
    values="snow",
    sort_columns=True,
    aggregate_function="mean"
)

stations_years
shape: (63, 93)
station 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026
str f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64
"Mount Wells" null null null null null null null null null null null null null null null null null 127.0 122.0 178.666667 110.5 131.0 143.0 147.0 145.666667 155.0 141.0 183.666667 133.0 166.0 141.333333 145.333333 182.5 169.333333 155.666667 112.0 103.833333 132.4 108.8 98.2 102.2 102.2 149.2 156.0 82.0 123.2 90.6 104.0 149.2 65.4 70.8 100.4 94.6 160.166667 103.6 166.75 107.4 135.4 159.8 95.6 92.0 147.4 79.8 131.2 142.75 88.8 147.0 131.2 135.6 107.0 84.0 78.8 123.0
"Mount Penrose" null null null null null null null null null null null null null null null null null null null null null null null null null 16.5 31.333333 12.0 null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null
"Green Mountain" null null null null null null null null null null null null null null null null null null null null null null null null null 144.0 205.0 131.75 175.5 230.0 175.333333 194.5 198.0 229.25 192.5 118.25 93.333333 170.875 143.0 56.375 53.0 119.0 162.75 157.0 null null null null null null null null null null null null null null null null null null null null null null null null null null null null null
"Bralorne" null null null null null null null null null null null null null null null null null null null null null null null null null null null null 11.0 37.5 46.333333 42.333333 60.0 39.5 61.666667 43.0 32.2 43.75 27.75 18.75 36.5 54.2 42.0 64.2 36.6 81.2 38.4 29.4 47.8 30.6 32.0 16.8 31.8 64.0 38.6 27.4 46.0 56.2 43.6 43.5 42.0 11.25 39.4 52.2 54.0 38.2 22.5 41.8 52.0 45.0 34.0 null null
"Shalalth" null null null null null null null null null null null null null null null null null null null null null null null null null null null null 47.75 81.333333 84.666667 77.0 89.833333 75.5 90.75 null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null
"Sumallo River" null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null 85.5 70.75 19.75 48.75 34.25 42.25 null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null
"Sumallo River West" null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null 6.25 41.5 11.25 23.25 16.5 110.25 36.75 93.75 54.75 42.0 68.25 18.0 42.75 5.25 40.75 61.25 108.333333 64.25 13.0 81.5 95.5 54.666667 51.6 2.5 17.4 53.25 98.666667 31.0 68.75 49.75 52.0 30.25 4.25 0.0 28.0
"Lightning Lake" null null null null null null null null null null null null 117.0 140.0 155.0 173.0 160.0 119.0 127.0 188.0 130.0 178.0 94.0 79.0 114.0 99.0 122.0 76.0 81.0 147.0 117.0 109.0 100.5 94.0 104.0 99.0 77.333333 112.333333 46.666667 56.0 41.0 78.0 95.333333 122.333333 67.333333 141.0 69.333333 55.0 83.666667 62.0 67.666667 14.333333 88.666667 87.0 106.0 71.0 67.333333 103.666667 127.666667 82.333333 90.333333 49.666667 79.0 73.666667 97.333333 51.333333 91.666667 90.333333 78.333333 71.333333 51.666667 33.333333 null
"Klesilkwa" null null null null null null null null null null null null 44.0 132.0 162.0 176.0 142.333333 103.333333 107.666667 190.333333 142.0 188.666667 99.333333 50.75 100.666667 83.0 58.0 45.666667 15.0 121.0 90.666667 92.333333 122.666667 35.666667 105.5 76.0 70.4 99.0 15.6 42.0 13.6 29.2 16.4 122.6 43.25 124.25 61.8 25.0 96.2 23.6 52.4 4.8 57.0 75.25 81.5 92.0 17.0 77.8 77.0 68.75 48.8 6.0 32.2 55.6 63.0 37.4 82.0 62.4 58.2 31.0 5.6 9.2 35.0
"Mount Sheba" null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null 173.75 182.666667 225.0 254.6 221.4 130.4 214.6 196.8 195.6 255.8 165.8 223.2 186.0 134.4 225.8 141.2 143.2 176.6 146.6 283.0 216.0 204.2 180.0 214.4 248.2 209.0 238.8 177.0 147.6 160.75 215.6 220.75 254.2 238.5 224.75 187.75 null null null

This clearly shows that the data was not collected on all stations for all years. If we want to see trends over time, this is not good, particularly since not all stations are at the same elevation (if early years mostly had low elevations stations and recent years have more stations in the alpine, we would get a totally fake signal).

We need to select a period and a set of stations that are monitored throughout that period. This is called a balanced panel.

Let’s define a function that returns the number of stations that have data collected for each season between 2 particular seasons:

def n_valid_in_period(df, period_start, period_end):
    test_seasons = range(period_start, period_end + 1)

    # Filter data for the test seasons
    test_seasons_subset = df.filter(pl.col("season").is_in(test_seasons))

    # Count seasons per station
    station_counts = test_seasons_subset.group_by("station").agg(
        pl.col("season").n_unique().alias("n_seasons")
    )

    # Filter stations with data for all test seasons
    valid_stations = station_counts.filter(pl.col("n_seasons") == len(test_seasons))

    n_valid = len(valid_stations)

    return n_valid, period_start, period_end

We can test our function:

print(n_valid_in_period(season_data, 1998, 2001))
(29, 1998, 2001)

This means that 29 stations have data collected every season between 1998 and 2001.

Now we need to know the earliest and latest seasons in our dataset:

seasons = season_data.select(pl.col("season"))
min_season = seasons.min().item()
max_season = seasons.max().item()
print(f"Seasons range: {min_season} to {max_season}")
Seasons range: 1935 to 2026

We can create a list the number of stations present in the whole period for each period spanning at least 10 seasons:

list_n_valid = []

for i in range(min_season, max_season + 1):
    for j in range(min_season, max_season + 1):
        if j - i > 9:         # we want a period of at least 10 seasons
            list_n_valid.append(n_valid_in_period(season_data, i, j))

We want at least 5 stations, so let’s clean the list from all n_valid < 5:

selected_list_n_valid = [i for i in list_n_valid if i[0] >= 5]

print(selected_list_n_valid)
[(5, 1947, 1957), (5, 1947, 1958), (5, 1947, 1959), (5, 1947, 1960), (5, 1947, 1961), (5, 1947, 1962), (5, 1947, 1963), (5, 1947, 1964), (5, 1947, 1965), (5, 1947, 1966), (5, 1947, 1967), (5, 1947, 1968), (5, 1947, 1969), (5, 1947, 1970), (5, 1947, 1971), (5, 1947, 1972), (5, 1947, 1973), (5, 1947, 1974), (5, 1947, 1975), (5, 1947, 1976), (5, 1947, 1977), (5, 1947, 1978), (5, 1947, 1979), (5, 1947, 1980), (5, 1947, 1981), (5, 1947, 1982), (5, 1947, 1983), (5, 1947, 1984), (5, 1948, 1958), (5, 1948, 1959), (5, 1948, 1960), (5, 1948, 1961), (5, 1948, 1962), (5, 1948, 1963), (5, 1948, 1964), (5, 1948, 1965), (5, 1948, 1966), (5, 1948, 1967), (5, 1948, 1968), (5, 1948, 1969), (5, 1948, 1970), (5, 1948, 1971), (5, 1948, 1972), (5, 1948, 1973), (5, 1948, 1974), (5, 1948, 1975), (5, 1948, 1976), (5, 1948, 1977), (5, 1948, 1978), (5, 1948, 1979), (5, 1948, 1980), (5, 1948, 1981), (5, 1948, 1982), (5, 1948, 1983), (5, 1948, 1984), (5, 1949, 1959), (5, 1949, 1960), (5, 1949, 1961), (5, 1949, 1962), (5, 1949, 1963), (5, 1949, 1964), (5, 1949, 1965), (5, 1949, 1966), (5, 1949, 1967), (5, 1949, 1968), (5, 1949, 1969), (5, 1949, 1970), (5, 1949, 1971), (5, 1949, 1972), (5, 1949, 1973), (5, 1949, 1974), (5, 1949, 1975), (5, 1949, 1976), (5, 1949, 1977), (5, 1949, 1978), (5, 1949, 1979), (5, 1949, 1980), (5, 1949, 1981), (5, 1949, 1982), (5, 1949, 1983), (5, 1949, 1984), (6, 1950, 1960), (6, 1950, 1961), (6, 1950, 1962), (6, 1950, 1963), (6, 1950, 1964), (6, 1950, 1965), (6, 1950, 1966), (6, 1950, 1967), (6, 1950, 1968), (6, 1950, 1969), (6, 1950, 1970), (6, 1950, 1971), (6, 1950, 1972), (5, 1950, 1973), (5, 1950, 1974), (5, 1950, 1975), (5, 1950, 1976), (5, 1950, 1977), (5, 1950, 1978), (5, 1950, 1979), (5, 1950, 1980), (5, 1950, 1981), (5, 1950, 1982), (5, 1950, 1983), (5, 1950, 1984), (6, 1951, 1961), (6, 1951, 1962), (6, 1951, 1963), (6, 1951, 1964), (6, 1951, 1965), (6, 1951, 1966), (6, 1951, 1967), (6, 1951, 1968), (6, 1951, 1969), (6, 1951, 1970), (6, 1951, 1971), (6, 1951, 1972), (5, 1951, 1973), (5, 1951, 1974), (5, 1951, 1975), (5, 1951, 1976), (5, 1951, 1977), (5, 1951, 1978), (5, 1951, 1979), (5, 1951, 1980), (5, 1951, 1981), (5, 1951, 1982), (5, 1951, 1983), (5, 1951, 1984), (7, 1952, 1962), (7, 1952, 1963), (7, 1952, 1964), (7, 1952, 1965), (7, 1952, 1966), (7, 1952, 1967), (7, 1952, 1968), (7, 1952, 1969), (7, 1952, 1970), (7, 1952, 1971), (7, 1952, 1972), (6, 1952, 1973), (6, 1952, 1974), (6, 1952, 1975), (6, 1952, 1976), (6, 1952, 1977), (6, 1952, 1978), (6, 1952, 1979), (6, 1952, 1980), (6, 1952, 1981), (6, 1952, 1982), (6, 1952, 1983), (6, 1952, 1984), (5, 1952, 1985), (5, 1952, 1986), (5, 1952, 1987), (9, 1953, 1963), (9, 1953, 1964), (8, 1953, 1965), (8, 1953, 1966), (8, 1953, 1967), (8, 1953, 1968), (8, 1953, 1969), (8, 1953, 1970), (8, 1953, 1971), (8, 1953, 1972), (7, 1953, 1973), (7, 1953, 1974), (7, 1953, 1975), (7, 1953, 1976), (7, 1953, 1977), (7, 1953, 1978), (7, 1953, 1979), (7, 1953, 1980), (7, 1953, 1981), (7, 1953, 1982), (7, 1953, 1983), (7, 1953, 1984), (6, 1953, 1985), (6, 1953, 1986), (6, 1953, 1987), (5, 1953, 1988), (5, 1953, 1989), (5, 1953, 1990), (5, 1953, 1991), (5, 1953, 1992), (5, 1953, 1993), (5, 1953, 1994), (5, 1953, 1995), (5, 1953, 1996), (5, 1953, 1997), (5, 1953, 1998), (5, 1953, 1999), (5, 1953, 2000), (5, 1953, 2001), (5, 1953, 2002), (5, 1953, 2003), (5, 1953, 2004), (5, 1953, 2005), (11, 1954, 1964), (10, 1954, 1965), (10, 1954, 1966), (9, 1954, 1967), (9, 1954, 1968), (9, 1954, 1969), (9, 1954, 1970), (9, 1954, 1971), (9, 1954, 1972), (8, 1954, 1973), (8, 1954, 1974), (8, 1954, 1975), (8, 1954, 1976), (8, 1954, 1977), (8, 1954, 1978), (8, 1954, 1979), (8, 1954, 1980), (8, 1954, 1981), (8, 1954, 1982), (8, 1954, 1983), (8, 1954, 1984), (7, 1954, 1985), (7, 1954, 1986), (7, 1954, 1987), (6, 1954, 1988), (6, 1954, 1989), (6, 1954, 1990), (6, 1954, 1991), (6, 1954, 1992), (6, 1954, 1993), (6, 1954, 1994), (6, 1954, 1995), (6, 1954, 1996), (6, 1954, 1997), (6, 1954, 1998), (6, 1954, 1999), (6, 1954, 2000), (6, 1954, 2001), (6, 1954, 2002), (6, 1954, 2003), (6, 1954, 2004), (6, 1954, 2005), (5, 1954, 2006), (5, 1954, 2007), (5, 1954, 2008), (5, 1954, 2009), (5, 1954, 2010), (5, 1954, 2011), (5, 1954, 2012), (5, 1954, 2013), (5, 1954, 2014), (5, 1954, 2015), (5, 1954, 2016), (5, 1954, 2017), (5, 1954, 2018), (5, 1954, 2019), (5, 1954, 2020), (5, 1954, 2021), (5, 1954, 2022), (5, 1954, 2023), (5, 1954, 2024), (5, 1954, 2025), (10, 1955, 1965), (10, 1955, 1966), (9, 1955, 1967), (9, 1955, 1968), (9, 1955, 1969), (9, 1955, 1970), (9, 1955, 1971), (9, 1955, 1972), (8, 1955, 1973), (8, 1955, 1974), (8, 1955, 1975), (8, 1955, 1976), (8, 1955, 1977), (8, 1955, 1978), (8, 1955, 1979), (8, 1955, 1980), (8, 1955, 1981), (8, 1955, 1982), (8, 1955, 1983), (8, 1955, 1984), (7, 1955, 1985), (7, 1955, 1986), (7, 1955, 1987), (6, 1955, 1988), (6, 1955, 1989), (6, 1955, 1990), (6, 1955, 1991), (6, 1955, 1992), (6, 1955, 1993), (6, 1955, 1994), (6, 1955, 1995), (6, 1955, 1996), (6, 1955, 1997), (6, 1955, 1998), (6, 1955, 1999), (6, 1955, 2000), (6, 1955, 2001), (6, 1955, 2002), (6, 1955, 2003), (6, 1955, 2004), (6, 1955, 2005), (5, 1955, 2006), (5, 1955, 2007), (5, 1955, 2008), (5, 1955, 2009), (5, 1955, 2010), (5, 1955, 2011), (5, 1955, 2012), (5, 1955, 2013), (5, 1955, 2014), (5, 1955, 2015), (5, 1955, 2016), (5, 1955, 2017), (5, 1955, 2018), (5, 1955, 2019), (5, 1955, 2020), (5, 1955, 2021), (5, 1955, 2022), (5, 1955, 2023), (5, 1955, 2024), (5, 1955, 2025), (10, 1956, 1966), (9, 1956, 1967), (9, 1956, 1968), (9, 1956, 1969), (9, 1956, 1970), (9, 1956, 1971), (9, 1956, 1972), (8, 1956, 1973), (8, 1956, 1974), (8, 1956, 1975), (8, 1956, 1976), (8, 1956, 1977), (8, 1956, 1978), (8, 1956, 1979), (8, 1956, 1980), (8, 1956, 1981), (8, 1956, 1982), (8, 1956, 1983), (8, 1956, 1984), (7, 1956, 1985), (7, 1956, 1986), (7, 1956, 1987), (6, 1956, 1988), (6, 1956, 1989), (6, 1956, 1990), (6, 1956, 1991), (6, 1956, 1992), (6, 1956, 1993), (6, 1956, 1994), (6, 1956, 1995), (6, 1956, 1996), (6, 1956, 1997), (6, 1956, 1998), (6, 1956, 1999), (6, 1956, 2000), (6, 1956, 2001), (6, 1956, 2002), (6, 1956, 2003), (6, 1956, 2004), (6, 1956, 2005), (5, 1956, 2006), (5, 1956, 2007), (5, 1956, 2008), (5, 1956, 2009), (5, 1956, 2010), (5, 1956, 2011), (5, 1956, 2012), (5, 1956, 2013), (5, 1956, 2014), (5, 1956, 2015), (5, 1956, 2016), (5, 1956, 2017), (5, 1956, 2018), (5, 1956, 2019), (5, 1956, 2020), (5, 1956, 2021), (5, 1956, 2022), (5, 1956, 2023), (5, 1956, 2024), (5, 1956, 2025), (9, 1957, 1967), (9, 1957, 1968), (9, 1957, 1969), (9, 1957, 1970), (9, 1957, 1971), (9, 1957, 1972), (8, 1957, 1973), (8, 1957, 1974), (8, 1957, 1975), (8, 1957, 1976), (8, 1957, 1977), (8, 1957, 1978), (8, 1957, 1979), (8, 1957, 1980), (8, 1957, 1981), (8, 1957, 1982), (8, 1957, 1983), (8, 1957, 1984), (7, 1957, 1985), (7, 1957, 1986), (7, 1957, 1987), (6, 1957, 1988), (6, 1957, 1989), (6, 1957, 1990), (6, 1957, 1991), (6, 1957, 1992), (6, 1957, 1993), (6, 1957, 1994), (6, 1957, 1995), (6, 1957, 1996), (6, 1957, 1997), (6, 1957, 1998), (6, 1957, 1999), (6, 1957, 2000), (6, 1957, 2001), (6, 1957, 2002), (6, 1957, 2003), (6, 1957, 2004), (6, 1957, 2005), (5, 1957, 2006), (5, 1957, 2007), (5, 1957, 2008), (5, 1957, 2009), (5, 1957, 2010), (5, 1957, 2011), (5, 1957, 2012), (5, 1957, 2013), (5, 1957, 2014), (5, 1957, 2015), (5, 1957, 2016), (5, 1957, 2017), (5, 1957, 2018), (5, 1957, 2019), (5, 1957, 2020), (5, 1957, 2021), (5, 1957, 2022), (5, 1957, 2023), (5, 1957, 2024), (5, 1957, 2025), (11, 1958, 1968), (11, 1958, 1969), (11, 1958, 1970), (11, 1958, 1971), (11, 1958, 1972), (10, 1958, 1973), (10, 1958, 1974), (10, 1958, 1975), (9, 1958, 1976), (9, 1958, 1977), (9, 1958, 1978), (9, 1958, 1979), (9, 1958, 1980), (9, 1958, 1981), (9, 1958, 1982), (9, 1958, 1983), (9, 1958, 1984), (8, 1958, 1985), (8, 1958, 1986), (8, 1958, 1987), (7, 1958, 1988), (7, 1958, 1989), (7, 1958, 1990), (7, 1958, 1991), (7, 1958, 1992), (7, 1958, 1993), (7, 1958, 1994), (7, 1958, 1995), (7, 1958, 1996), (7, 1958, 1997), (7, 1958, 1998), (7, 1958, 1999), (7, 1958, 2000), (7, 1958, 2001), (7, 1958, 2002), (7, 1958, 2003), (7, 1958, 2004), (7, 1958, 2005), (6, 1958, 2006), (6, 1958, 2007), (6, 1958, 2008), (6, 1958, 2009), (6, 1958, 2010), (6, 1958, 2011), (6, 1958, 2012), (6, 1958, 2013), (6, 1958, 2014), (6, 1958, 2015), (6, 1958, 2016), (6, 1958, 2017), (6, 1958, 2018), (6, 1958, 2019), (6, 1958, 2020), (6, 1958, 2021), (6, 1958, 2022), (6, 1958, 2023), (6, 1958, 2024), (6, 1958, 2025), (5, 1958, 2026), (13, 1959, 1969), (13, 1959, 1970), (13, 1959, 1971), (13, 1959, 1972), (12, 1959, 1973), (12, 1959, 1974), (12, 1959, 1975), (11, 1959, 1976), (11, 1959, 1977), (11, 1959, 1978), (11, 1959, 1979), (11, 1959, 1980), (11, 1959, 1981), (11, 1959, 1982), (11, 1959, 1983), (11, 1959, 1984), (10, 1959, 1985), (10, 1959, 1986), (10, 1959, 1987), (9, 1959, 1988), (9, 1959, 1989), (9, 1959, 1990), (9, 1959, 1991), (9, 1959, 1992), (9, 1959, 1993), (9, 1959, 1994), (8, 1959, 1995), (8, 1959, 1996), (7, 1959, 1997), (7, 1959, 1998), (7, 1959, 1999), (7, 1959, 2000), (7, 1959, 2001), (7, 1959, 2002), (7, 1959, 2003), (7, 1959, 2004), (7, 1959, 2005), (6, 1959, 2006), (6, 1959, 2007), (6, 1959, 2008), (6, 1959, 2009), (6, 1959, 2010), (6, 1959, 2011), (6, 1959, 2012), (6, 1959, 2013), (6, 1959, 2014), (6, 1959, 2015), (6, 1959, 2016), (6, 1959, 2017), (6, 1959, 2018), (6, 1959, 2019), (6, 1959, 2020), (6, 1959, 2021), (6, 1959, 2022), (6, 1959, 2023), (6, 1959, 2024), (6, 1959, 2025), (5, 1959, 2026), (15, 1960, 1970), (15, 1960, 1971), (15, 1960, 1972), (14, 1960, 1973), (14, 1960, 1974), (14, 1960, 1975), (13, 1960, 1976), (13, 1960, 1977), (13, 1960, 1978), (13, 1960, 1979), (13, 1960, 1980), (13, 1960, 1981), (13, 1960, 1982), (13, 1960, 1983), (13, 1960, 1984), (12, 1960, 1985), (12, 1960, 1986), (12, 1960, 1987), (11, 1960, 1988), (11, 1960, 1989), (10, 1960, 1990), (10, 1960, 1991), (10, 1960, 1992), (10, 1960, 1993), (10, 1960, 1994), (9, 1960, 1995), (9, 1960, 1996), (8, 1960, 1997), (7, 1960, 1998), (7, 1960, 1999), (7, 1960, 2000), (7, 1960, 2001), (7, 1960, 2002), (7, 1960, 2003), (7, 1960, 2004), (7, 1960, 2005), (6, 1960, 2006), (6, 1960, 2007), (6, 1960, 2008), (6, 1960, 2009), (6, 1960, 2010), (6, 1960, 2011), (6, 1960, 2012), (6, 1960, 2013), (6, 1960, 2014), (6, 1960, 2015), (6, 1960, 2016), (6, 1960, 2017), (6, 1960, 2018), (6, 1960, 2019), (6, 1960, 2020), (6, 1960, 2021), (6, 1960, 2022), (6, 1960, 2023), (6, 1960, 2024), (6, 1960, 2025), (5, 1960, 2026), (16, 1961, 1971), (16, 1961, 1972), (15, 1961, 1973), (15, 1961, 1974), (15, 1961, 1975), (14, 1961, 1976), (14, 1961, 1977), (14, 1961, 1978), (14, 1961, 1979), (14, 1961, 1980), (14, 1961, 1981), (14, 1961, 1982), (14, 1961, 1983), (14, 1961, 1984), (13, 1961, 1985), (13, 1961, 1986), (13, 1961, 1987), (12, 1961, 1988), (12, 1961, 1989), (11, 1961, 1990), (11, 1961, 1991), (11, 1961, 1992), (11, 1961, 1993), (11, 1961, 1994), (10, 1961, 1995), (10, 1961, 1996), (8, 1961, 1997), (7, 1961, 1998), (7, 1961, 1999), (7, 1961, 2000), (7, 1961, 2001), (7, 1961, 2002), (7, 1961, 2003), (7, 1961, 2004), (7, 1961, 2005), (6, 1961, 2006), (6, 1961, 2007), (6, 1961, 2008), (6, 1961, 2009), (6, 1961, 2010), (6, 1961, 2011), (6, 1961, 2012), (6, 1961, 2013), (6, 1961, 2014), (6, 1961, 2015), (6, 1961, 2016), (6, 1961, 2017), (6, 1961, 2018), (6, 1961, 2019), (6, 1961, 2020), (6, 1961, 2021), (6, 1961, 2022), (6, 1961, 2023), (6, 1961, 2024), (6, 1961, 2025), (5, 1961, 2026), (16, 1962, 1972), (15, 1962, 1973), (15, 1962, 1974), (15, 1962, 1975), (14, 1962, 1976), (14, 1962, 1977), (14, 1962, 1978), (14, 1962, 1979), (14, 1962, 1980), (14, 1962, 1981), (14, 1962, 1982), (14, 1962, 1983), (14, 1962, 1984), (13, 1962, 1985), (13, 1962, 1986), (13, 1962, 1987), (12, 1962, 1988), (12, 1962, 1989), (11, 1962, 1990), (11, 1962, 1991), (11, 1962, 1992), (11, 1962, 1993), (11, 1962, 1994), (10, 1962, 1995), (10, 1962, 1996), (8, 1962, 1997), (7, 1962, 1998), (7, 1962, 1999), (7, 1962, 2000), (7, 1962, 2001), (7, 1962, 2002), (7, 1962, 2003), (7, 1962, 2004), (7, 1962, 2005), (6, 1962, 2006), (6, 1962, 2007), (6, 1962, 2008), (6, 1962, 2009), (6, 1962, 2010), (6, 1962, 2011), (6, 1962, 2012), (6, 1962, 2013), (6, 1962, 2014), (6, 1962, 2015), (6, 1962, 2016), (6, 1962, 2017), (6, 1962, 2018), (6, 1962, 2019), (6, 1962, 2020), (6, 1962, 2021), (6, 1962, 2022), (6, 1962, 2023), (6, 1962, 2024), (6, 1962, 2025), (5, 1962, 2026), (16, 1963, 1973), (16, 1963, 1974), (16, 1963, 1975), (15, 1963, 1976), (15, 1963, 1977), (15, 1963, 1978), (15, 1963, 1979), (15, 1963, 1980), (15, 1963, 1981), (15, 1963, 1982), (15, 1963, 1983), (15, 1963, 1984), (14, 1963, 1985), (14, 1963, 1986), (14, 1963, 1987), (13, 1963, 1988), (13, 1963, 1989), (12, 1963, 1990), (12, 1963, 1991), (12, 1963, 1992), (12, 1963, 1993), (12, 1963, 1994), (11, 1963, 1995), (11, 1963, 1996), (9, 1963, 1997), (8, 1963, 1998), (8, 1963, 1999), (8, 1963, 2000), (8, 1963, 2001), (8, 1963, 2002), (8, 1963, 2003), (8, 1963, 2004), (8, 1963, 2005), (7, 1963, 2006), (7, 1963, 2007), (7, 1963, 2008), (7, 1963, 2009), (7, 1963, 2010), (7, 1963, 2011), (7, 1963, 2012), (7, 1963, 2013), (7, 1963, 2014), (7, 1963, 2015), (7, 1963, 2016), (7, 1963, 2017), (7, 1963, 2018), (7, 1963, 2019), (7, 1963, 2020), (7, 1963, 2021), (7, 1963, 2022), (7, 1963, 2023), (7, 1963, 2024), (6, 1963, 2025), (5, 1963, 2026), (16, 1964, 1974), (16, 1964, 1975), (15, 1964, 1976), (15, 1964, 1977), (15, 1964, 1978), (15, 1964, 1979), (15, 1964, 1980), (15, 1964, 1981), (15, 1964, 1982), (15, 1964, 1983), (15, 1964, 1984), (14, 1964, 1985), (14, 1964, 1986), (14, 1964, 1987), (13, 1964, 1988), (13, 1964, 1989), (12, 1964, 1990), (12, 1964, 1991), (12, 1964, 1992), (12, 1964, 1993), (12, 1964, 1994), (11, 1964, 1995), (11, 1964, 1996), (9, 1964, 1997), (8, 1964, 1998), (8, 1964, 1999), (8, 1964, 2000), (8, 1964, 2001), (8, 1964, 2002), (8, 1964, 2003), (8, 1964, 2004), (8, 1964, 2005), (7, 1964, 2006), (7, 1964, 2007), (7, 1964, 2008), (7, 1964, 2009), (7, 1964, 2010), (7, 1964, 2011), (7, 1964, 2012), (7, 1964, 2013), (7, 1964, 2014), (7, 1964, 2015), (7, 1964, 2016), (7, 1964, 2017), (7, 1964, 2018), (7, 1964, 2019), (7, 1964, 2020), (7, 1964, 2021), (7, 1964, 2022), (7, 1964, 2023), (7, 1964, 2024), (6, 1964, 2025), (5, 1964, 2026), (17, 1965, 1975), (16, 1965, 1976), (16, 1965, 1977), (16, 1965, 1978), (16, 1965, 1979), (16, 1965, 1980), (16, 1965, 1981), (15, 1965, 1982), (15, 1965, 1983), (15, 1965, 1984), (14, 1965, 1985), (14, 1965, 1986), (14, 1965, 1987), (13, 1965, 1988), (13, 1965, 1989), (12, 1965, 1990), (12, 1965, 1991), (12, 1965, 1992), (12, 1965, 1993), (12, 1965, 1994), (11, 1965, 1995), (11, 1965, 1996), (9, 1965, 1997), (8, 1965, 1998), (8, 1965, 1999), (8, 1965, 2000), (8, 1965, 2001), (8, 1965, 2002), (8, 1965, 2003), (8, 1965, 2004), (8, 1965, 2005), (7, 1965, 2006), (7, 1965, 2007), (7, 1965, 2008), (7, 1965, 2009), (7, 1965, 2010), (7, 1965, 2011), (7, 1965, 2012), (7, 1965, 2013), (7, 1965, 2014), (7, 1965, 2015), (7, 1965, 2016), (7, 1965, 2017), (7, 1965, 2018), (7, 1965, 2019), (7, 1965, 2020), (7, 1965, 2021), (7, 1965, 2022), (7, 1965, 2023), (7, 1965, 2024), (6, 1965, 2025), (5, 1965, 2026), (17, 1966, 1976), (17, 1966, 1977), (17, 1966, 1978), (17, 1966, 1979), (17, 1966, 1980), (17, 1966, 1981), (16, 1966, 1982), (16, 1966, 1983), (16, 1966, 1984), (14, 1966, 1985), (14, 1966, 1986), (14, 1966, 1987), (13, 1966, 1988), (13, 1966, 1989), (12, 1966, 1990), (12, 1966, 1991), (12, 1966, 1992), (12, 1966, 1993), (12, 1966, 1994), (11, 1966, 1995), (11, 1966, 1996), (9, 1966, 1997), (8, 1966, 1998), (8, 1966, 1999), (8, 1966, 2000), (8, 1966, 2001), (8, 1966, 2002), (8, 1966, 2003), (8, 1966, 2004), (8, 1966, 2005), (7, 1966, 2006), (7, 1966, 2007), (7, 1966, 2008), (7, 1966, 2009), (7, 1966, 2010), (7, 1966, 2011), (7, 1966, 2012), (7, 1966, 2013), (7, 1966, 2014), (7, 1966, 2015), (7, 1966, 2016), (7, 1966, 2017), (7, 1966, 2018), (7, 1966, 2019), (7, 1966, 2020), (7, 1966, 2021), (7, 1966, 2022), (7, 1966, 2023), (7, 1966, 2024), (6, 1966, 2025), (5, 1966, 2026), (20, 1967, 1977), (20, 1967, 1978), (20, 1967, 1979), (20, 1967, 1980), (20, 1967, 1981), (19, 1967, 1982), (19, 1967, 1983), (19, 1967, 1984), (17, 1967, 1985), (17, 1967, 1986), (17, 1967, 1987), (16, 1967, 1988), (16, 1967, 1989), (15, 1967, 1990), (15, 1967, 1991), (15, 1967, 1992), (15, 1967, 1993), (15, 1967, 1994), (14, 1967, 1995), (14, 1967, 1996), (11, 1967, 1997), (10, 1967, 1998), (10, 1967, 1999), (10, 1967, 2000), (10, 1967, 2001), (10, 1967, 2002), (10, 1967, 2003), (10, 1967, 2004), (10, 1967, 2005), (9, 1967, 2006), (9, 1967, 2007), (9, 1967, 2008), (9, 1967, 2009), (9, 1967, 2010), (9, 1967, 2011), (9, 1967, 2012), (9, 1967, 2013), (9, 1967, 2014), (9, 1967, 2015), (9, 1967, 2016), (9, 1967, 2017), (9, 1967, 2018), (9, 1967, 2019), (9, 1967, 2020), (9, 1967, 2021), (8, 1967, 2022), (8, 1967, 2023), (8, 1967, 2024), (6, 1967, 2025), (5, 1967, 2026), (21, 1968, 1978), (21, 1968, 1979), (21, 1968, 1980), (21, 1968, 1981), (20, 1968, 1982), (20, 1968, 1983), (20, 1968, 1984), (18, 1968, 1985), (18, 1968, 1986), (18, 1968, 1987), (17, 1968, 1988), (17, 1968, 1989), (16, 1968, 1990), (16, 1968, 1991), (16, 1968, 1992), (16, 1968, 1993), (16, 1968, 1994), (15, 1968, 1995), (15, 1968, 1996), (12, 1968, 1997), (11, 1968, 1998), (11, 1968, 1999), (11, 1968, 2000), (11, 1968, 2001), (11, 1968, 2002), (11, 1968, 2003), (11, 1968, 2004), (11, 1968, 2005), (10, 1968, 2006), (10, 1968, 2007), (10, 1968, 2008), (10, 1968, 2009), (10, 1968, 2010), (10, 1968, 2011), (10, 1968, 2012), (10, 1968, 2013), (10, 1968, 2014), (10, 1968, 2015), (10, 1968, 2016), (10, 1968, 2017), (10, 1968, 2018), (10, 1968, 2019), (10, 1968, 2020), (10, 1968, 2021), (9, 1968, 2022), (9, 1968, 2023), (9, 1968, 2024), (7, 1968, 2025), (6, 1968, 2026), (22, 1969, 1979), (22, 1969, 1980), (22, 1969, 1981), (21, 1969, 1982), (21, 1969, 1983), (21, 1969, 1984), (19, 1969, 1985), (19, 1969, 1986), (19, 1969, 1987), (18, 1969, 1988), (18, 1969, 1989), (17, 1969, 1990), (17, 1969, 1991), (17, 1969, 1992), (17, 1969, 1993), (17, 1969, 1994), (16, 1969, 1995), (16, 1969, 1996), (13, 1969, 1997), (12, 1969, 1998), (12, 1969, 1999), (12, 1969, 2000), (12, 1969, 2001), (12, 1969, 2002), (12, 1969, 2003), (12, 1969, 2004), (12, 1969, 2005), (11, 1969, 2006), (11, 1969, 2007), (11, 1969, 2008), (11, 1969, 2009), (11, 1969, 2010), (11, 1969, 2011), (11, 1969, 2012), (11, 1969, 2013), (11, 1969, 2014), (11, 1969, 2015), (11, 1969, 2016), (11, 1969, 2017), (11, 1969, 2018), (11, 1969, 2019), (11, 1969, 2020), (11, 1969, 2021), (10, 1969, 2022), (10, 1969, 2023), (9, 1969, 2024), (7, 1969, 2025), (6, 1969, 2026), (26, 1970, 1980), (26, 1970, 1981), (25, 1970, 1982), (25, 1970, 1983), (25, 1970, 1984), (23, 1970, 1985), (23, 1970, 1986), (23, 1970, 1987), (22, 1970, 1988), (22, 1970, 1989), (21, 1970, 1990), (20, 1970, 1991), (20, 1970, 1992), (20, 1970, 1993), (20, 1970, 1994), (19, 1970, 1995), (18, 1970, 1996), (15, 1970, 1997), (14, 1970, 1998), (14, 1970, 1999), (14, 1970, 2000), (14, 1970, 2001), (14, 1970, 2002), (14, 1970, 2003), (14, 1970, 2004), (14, 1970, 2005), (13, 1970, 2006), (13, 1970, 2007), (13, 1970, 2008), (13, 1970, 2009), (13, 1970, 2010), (13, 1970, 2011), (13, 1970, 2012), (13, 1970, 2013), (13, 1970, 2014), (13, 1970, 2015), (13, 1970, 2016), (13, 1970, 2017), (13, 1970, 2018), (13, 1970, 2019), (13, 1970, 2020), (13, 1970, 2021), (12, 1970, 2022), (12, 1970, 2023), (11, 1970, 2024), (9, 1970, 2025), (7, 1970, 2026), (26, 1971, 1981), (25, 1971, 1982), (25, 1971, 1983), (25, 1971, 1984), (23, 1971, 1985), (23, 1971, 1986), (23, 1971, 1987), (22, 1971, 1988), (22, 1971, 1989), (21, 1971, 1990), (20, 1971, 1991), (20, 1971, 1992), (20, 1971, 1993), (20, 1971, 1994), (19, 1971, 1995), (18, 1971, 1996), (15, 1971, 1997), (14, 1971, 1998), (14, 1971, 1999), (14, 1971, 2000), (14, 1971, 2001), (14, 1971, 2002), (14, 1971, 2003), (14, 1971, 2004), (14, 1971, 2005), (13, 1971, 2006), (13, 1971, 2007), (13, 1971, 2008), (13, 1971, 2009), (13, 1971, 2010), (13, 1971, 2011), (13, 1971, 2012), (13, 1971, 2013), (13, 1971, 2014), (13, 1971, 2015), (13, 1971, 2016), (13, 1971, 2017), (13, 1971, 2018), (13, 1971, 2019), (13, 1971, 2020), (13, 1971, 2021), (12, 1971, 2022), (12, 1971, 2023), (11, 1971, 2024), (9, 1971, 2025), (7, 1971, 2026), (26, 1972, 1982), (26, 1972, 1983), (26, 1972, 1984), (24, 1972, 1985), (24, 1972, 1986), (24, 1972, 1987), (23, 1972, 1988), (23, 1972, 1989), (22, 1972, 1990), (21, 1972, 1991), (21, 1972, 1992), (21, 1972, 1993), (21, 1972, 1994), (20, 1972, 1995), (19, 1972, 1996), (16, 1972, 1997), (15, 1972, 1998), (15, 1972, 1999), (15, 1972, 2000), (15, 1972, 2001), (15, 1972, 2002), (15, 1972, 2003), (15, 1972, 2004), (15, 1972, 2005), (14, 1972, 2006), (14, 1972, 2007), (14, 1972, 2008), (14, 1972, 2009), (13, 1972, 2010), (13, 1972, 2011), (13, 1972, 2012), (13, 1972, 2013), (13, 1972, 2014), (13, 1972, 2015), (13, 1972, 2016), (13, 1972, 2017), (13, 1972, 2018), (13, 1972, 2019), (13, 1972, 2020), (13, 1972, 2021), (12, 1972, 2022), (12, 1972, 2023), (11, 1972, 2024), (9, 1972, 2025), (7, 1972, 2026), (26, 1973, 1983), (26, 1973, 1984), (24, 1973, 1985), (24, 1973, 1986), (24, 1973, 1987), (23, 1973, 1988), (23, 1973, 1989), (22, 1973, 1990), (21, 1973, 1991), (21, 1973, 1992), (21, 1973, 1993), (21, 1973, 1994), (20, 1973, 1995), (19, 1973, 1996), (16, 1973, 1997), (15, 1973, 1998), (15, 1973, 1999), (15, 1973, 2000), (15, 1973, 2001), (15, 1973, 2002), (15, 1973, 2003), (15, 1973, 2004), (15, 1973, 2005), (14, 1973, 2006), (14, 1973, 2007), (14, 1973, 2008), (14, 1973, 2009), (13, 1973, 2010), (13, 1973, 2011), (13, 1973, 2012), (13, 1973, 2013), (13, 1973, 2014), (13, 1973, 2015), (13, 1973, 2016), (13, 1973, 2017), (13, 1973, 2018), (13, 1973, 2019), (13, 1973, 2020), (13, 1973, 2021), (12, 1973, 2022), (12, 1973, 2023), (11, 1973, 2024), (9, 1973, 2025), (7, 1973, 2026), (29, 1974, 1984), (27, 1974, 1985), (26, 1974, 1986), (25, 1974, 1987), (24, 1974, 1988), (24, 1974, 1989), (23, 1974, 1990), (22, 1974, 1991), (22, 1974, 1992), (22, 1974, 1993), (22, 1974, 1994), (21, 1974, 1995), (20, 1974, 1996), (17, 1974, 1997), (16, 1974, 1998), (16, 1974, 1999), (16, 1974, 2000), (16, 1974, 2001), (16, 1974, 2002), (16, 1974, 2003), (16, 1974, 2004), (15, 1974, 2005), (14, 1974, 2006), (14, 1974, 2007), (14, 1974, 2008), (14, 1974, 2009), (13, 1974, 2010), (13, 1974, 2011), (13, 1974, 2012), (13, 1974, 2013), (13, 1974, 2014), (13, 1974, 2015), (13, 1974, 2016), (13, 1974, 2017), (13, 1974, 2018), (13, 1974, 2019), (13, 1974, 2020), (13, 1974, 2021), (12, 1974, 2022), (12, 1974, 2023), (11, 1974, 2024), (9, 1974, 2025), (7, 1974, 2026), (28, 1975, 1985), (27, 1975, 1986), (26, 1975, 1987), (25, 1975, 1988), (25, 1975, 1989), (24, 1975, 1990), (23, 1975, 1991), (22, 1975, 1992), (22, 1975, 1993), (22, 1975, 1994), (21, 1975, 1995), (20, 1975, 1996), (17, 1975, 1997), (16, 1975, 1998), (16, 1975, 1999), (16, 1975, 2000), (16, 1975, 2001), (16, 1975, 2002), (16, 1975, 2003), (16, 1975, 2004), (15, 1975, 2005), (14, 1975, 2006), (14, 1975, 2007), (14, 1975, 2008), (14, 1975, 2009), (13, 1975, 2010), (13, 1975, 2011), (13, 1975, 2012), (13, 1975, 2013), (13, 1975, 2014), (13, 1975, 2015), (13, 1975, 2016), (13, 1975, 2017), (13, 1975, 2018), (13, 1975, 2019), (13, 1975, 2020), (13, 1975, 2021), (12, 1975, 2022), (12, 1975, 2023), (11, 1975, 2024), (9, 1975, 2025), (7, 1975, 2026), (29, 1976, 1986), (28, 1976, 1987), (27, 1976, 1988), (27, 1976, 1989), (25, 1976, 1990), (24, 1976, 1991), (23, 1976, 1992), (23, 1976, 1993), (23, 1976, 1994), (22, 1976, 1995), (21, 1976, 1996), (18, 1976, 1997), (17, 1976, 1998), (17, 1976, 1999), (17, 1976, 2000), (17, 1976, 2001), (17, 1976, 2002), (17, 1976, 2003), (16, 1976, 2004), (15, 1976, 2005), (14, 1976, 2006), (14, 1976, 2007), (14, 1976, 2008), (14, 1976, 2009), (13, 1976, 2010), (13, 1976, 2011), (13, 1976, 2012), (13, 1976, 2013), (13, 1976, 2014), (13, 1976, 2015), (13, 1976, 2016), (13, 1976, 2017), (13, 1976, 2018), (13, 1976, 2019), (13, 1976, 2020), (13, 1976, 2021), (12, 1976, 2022), (12, 1976, 2023), (11, 1976, 2024), (9, 1976, 2025), (7, 1976, 2026), (29, 1977, 1987), (28, 1977, 1988), (28, 1977, 1989), (26, 1977, 1990), (25, 1977, 1991), (24, 1977, 1992), (24, 1977, 1993), (24, 1977, 1994), (23, 1977, 1995), (22, 1977, 1996), (19, 1977, 1997), (18, 1977, 1998), (17, 1977, 1999), (17, 1977, 2000), (17, 1977, 2001), (17, 1977, 2002), (17, 1977, 2003), (16, 1977, 2004), (15, 1977, 2005), (14, 1977, 2006), (14, 1977, 2007), (14, 1977, 2008), (14, 1977, 2009), (13, 1977, 2010), (13, 1977, 2011), (13, 1977, 2012), (13, 1977, 2013), (13, 1977, 2014), (13, 1977, 2015), (13, 1977, 2016), (13, 1977, 2017), (13, 1977, 2018), (13, 1977, 2019), (13, 1977, 2020), (13, 1977, 2021), (12, 1977, 2022), (12, 1977, 2023), (11, 1977, 2024), (9, 1977, 2025), (7, 1977, 2026), (29, 1978, 1988), (29, 1978, 1989), (27, 1978, 1990), (26, 1978, 1991), (25, 1978, 1992), (25, 1978, 1993), (25, 1978, 1994), (24, 1978, 1995), (23, 1978, 1996), (20, 1978, 1997), (19, 1978, 1998), (18, 1978, 1999), (18, 1978, 2000), (18, 1978, 2001), (18, 1978, 2002), (18, 1978, 2003), (17, 1978, 2004), (16, 1978, 2005), (15, 1978, 2006), (15, 1978, 2007), (15, 1978, 2008), (15, 1978, 2009), (14, 1978, 2010), (14, 1978, 2011), (14, 1978, 2012), (14, 1978, 2013), (14, 1978, 2014), (14, 1978, 2015), (14, 1978, 2016), (14, 1978, 2017), (14, 1978, 2018), (14, 1978, 2019), (14, 1978, 2020), (14, 1978, 2021), (13, 1978, 2022), (13, 1978, 2023), (12, 1978, 2024), (10, 1978, 2025), (8, 1978, 2026), (31, 1979, 1989), (29, 1979, 1990), (28, 1979, 1991), (27, 1979, 1992), (27, 1979, 1993), (27, 1979, 1994), (26, 1979, 1995), (24, 1979, 1996), (21, 1979, 1997), (20, 1979, 1998), (19, 1979, 1999), (19, 1979, 2000), (19, 1979, 2001), (19, 1979, 2002), (19, 1979, 2003), (18, 1979, 2004), (17, 1979, 2005), (16, 1979, 2006), (16, 1979, 2007), (16, 1979, 2008), (16, 1979, 2009), (15, 1979, 2010), (15, 1979, 2011), (15, 1979, 2012), (15, 1979, 2013), (15, 1979, 2014), (15, 1979, 2015), (15, 1979, 2016), (15, 1979, 2017), (15, 1979, 2018), (15, 1979, 2019), (15, 1979, 2020), (15, 1979, 2021), (14, 1979, 2022), (14, 1979, 2023), (13, 1979, 2024), (10, 1979, 2025), (8, 1979, 2026), (29, 1980, 1990), (28, 1980, 1991), (27, 1980, 1992), (27, 1980, 1993), (27, 1980, 1994), (26, 1980, 1995), (24, 1980, 1996), (21, 1980, 1997), (20, 1980, 1998), (19, 1980, 1999), (19, 1980, 2000), (19, 1980, 2001), (19, 1980, 2002), (19, 1980, 2003), (18, 1980, 2004), (17, 1980, 2005), (16, 1980, 2006), (16, 1980, 2007), (16, 1980, 2008), (16, 1980, 2009), (15, 1980, 2010), (15, 1980, 2011), (15, 1980, 2012), (15, 1980, 2013), (15, 1980, 2014), (15, 1980, 2015), (15, 1980, 2016), (15, 1980, 2017), (15, 1980, 2018), (15, 1980, 2019), (15, 1980, 2020), (15, 1980, 2021), (14, 1980, 2022), (14, 1980, 2023), (13, 1980, 2024), (10, 1980, 2025), (8, 1980, 2026), (28, 1981, 1991), (27, 1981, 1992), (27, 1981, 1993), (27, 1981, 1994), (26, 1981, 1995), (24, 1981, 1996), (21, 1981, 1997), (20, 1981, 1998), (19, 1981, 1999), (19, 1981, 2000), (19, 1981, 2001), (19, 1981, 2002), (19, 1981, 2003), (18, 1981, 2004), (17, 1981, 2005), (16, 1981, 2006), (16, 1981, 2007), (16, 1981, 2008), (16, 1981, 2009), (15, 1981, 2010), (15, 1981, 2011), (15, 1981, 2012), (15, 1981, 2013), (15, 1981, 2014), (15, 1981, 2015), (15, 1981, 2016), (15, 1981, 2017), (15, 1981, 2018), (15, 1981, 2019), (15, 1981, 2020), (15, 1981, 2021), (14, 1981, 2022), (14, 1981, 2023), (13, 1981, 2024), (10, 1981, 2025), (8, 1981, 2026), (27, 1982, 1992), (27, 1982, 1993), (27, 1982, 1994), (26, 1982, 1995), (24, 1982, 1996), (21, 1982, 1997), (20, 1982, 1998), (19, 1982, 1999), (19, 1982, 2000), (19, 1982, 2001), (19, 1982, 2002), (19, 1982, 2003), (18, 1982, 2004), (17, 1982, 2005), (16, 1982, 2006), (16, 1982, 2007), (16, 1982, 2008), (16, 1982, 2009), (15, 1982, 2010), (15, 1982, 2011), (15, 1982, 2012), (15, 1982, 2013), (15, 1982, 2014), (15, 1982, 2015), (15, 1982, 2016), (15, 1982, 2017), (15, 1982, 2018), (15, 1982, 2019), (15, 1982, 2020), (15, 1982, 2021), (14, 1982, 2022), (14, 1982, 2023), (13, 1982, 2024), (10, 1982, 2025), (8, 1982, 2026), (27, 1983, 1993), (27, 1983, 1994), (26, 1983, 1995), (24, 1983, 1996), (21, 1983, 1997), (20, 1983, 1998), (19, 1983, 1999), (19, 1983, 2000), (19, 1983, 2001), (19, 1983, 2002), (19, 1983, 2003), (18, 1983, 2004), (17, 1983, 2005), (16, 1983, 2006), (16, 1983, 2007), (16, 1983, 2008), (16, 1983, 2009), (15, 1983, 2010), (15, 1983, 2011), (15, 1983, 2012), (15, 1983, 2013), (15, 1983, 2014), (15, 1983, 2015), (15, 1983, 2016), (15, 1983, 2017), (15, 1983, 2018), (15, 1983, 2019), (15, 1983, 2020), (15, 1983, 2021), (14, 1983, 2022), (14, 1983, 2023), (13, 1983, 2024), (10, 1983, 2025), (8, 1983, 2026), (30, 1984, 1994), (29, 1984, 1995), (27, 1984, 1996), (24, 1984, 1997), (23, 1984, 1998), (22, 1984, 1999), (22, 1984, 2000), (22, 1984, 2001), (22, 1984, 2002), (22, 1984, 2003), (21, 1984, 2004), (20, 1984, 2005), (18, 1984, 2006), (18, 1984, 2007), (18, 1984, 2008), (18, 1984, 2009), (17, 1984, 2010), (17, 1984, 2011), (15, 1984, 2012), (15, 1984, 2013), (15, 1984, 2014), (15, 1984, 2015), (15, 1984, 2016), (15, 1984, 2017), (15, 1984, 2018), (15, 1984, 2019), (15, 1984, 2020), (15, 1984, 2021), (14, 1984, 2022), (14, 1984, 2023), (13, 1984, 2024), (10, 1984, 2025), (8, 1984, 2026), (30, 1985, 1995), (28, 1985, 1996), (25, 1985, 1997), (24, 1985, 1998), (23, 1985, 1999), (23, 1985, 2000), (23, 1985, 2001), (23, 1985, 2002), (23, 1985, 2003), (22, 1985, 2004), (21, 1985, 2005), (19, 1985, 2006), (19, 1985, 2007), (19, 1985, 2008), (19, 1985, 2009), (18, 1985, 2010), (18, 1985, 2011), (16, 1985, 2012), (16, 1985, 2013), (16, 1985, 2014), (16, 1985, 2015), (16, 1985, 2016), (16, 1985, 2017), (16, 1985, 2018), (16, 1985, 2019), (16, 1985, 2020), (16, 1985, 2021), (15, 1985, 2022), (15, 1985, 2023), (13, 1985, 2024), (10, 1985, 2025), (8, 1985, 2026), (29, 1986, 1996), (25, 1986, 1997), (24, 1986, 1998), (23, 1986, 1999), (23, 1986, 2000), (23, 1986, 2001), (23, 1986, 2002), (23, 1986, 2003), (22, 1986, 2004), (21, 1986, 2005), (19, 1986, 2006), (19, 1986, 2007), (19, 1986, 2008), (19, 1986, 2009), (18, 1986, 2010), (18, 1986, 2011), (16, 1986, 2012), (16, 1986, 2013), (16, 1986, 2014), (16, 1986, 2015), (16, 1986, 2016), (16, 1986, 2017), (16, 1986, 2018), (16, 1986, 2019), (16, 1986, 2020), (16, 1986, 2021), (15, 1986, 2022), (15, 1986, 2023), (13, 1986, 2024), (10, 1986, 2025), (8, 1986, 2026), (25, 1987, 1997), (24, 1987, 1998), (23, 1987, 1999), (23, 1987, 2000), (23, 1987, 2001), (23, 1987, 2002), (23, 1987, 2003), (22, 1987, 2004), (21, 1987, 2005), (19, 1987, 2006), (19, 1987, 2007), (19, 1987, 2008), (19, 1987, 2009), (18, 1987, 2010), (18, 1987, 2011), (16, 1987, 2012), (16, 1987, 2013), (16, 1987, 2014), (16, 1987, 2015), (16, 1987, 2016), (16, 1987, 2017), (16, 1987, 2018), (16, 1987, 2019), (16, 1987, 2020), (16, 1987, 2021), (15, 1987, 2022), (15, 1987, 2023), (13, 1987, 2024), (10, 1987, 2025), (8, 1987, 2026), (24, 1988, 1998), (23, 1988, 1999), (23, 1988, 2000), (23, 1988, 2001), (23, 1988, 2002), (23, 1988, 2003), (22, 1988, 2004), (21, 1988, 2005), (19, 1988, 2006), (19, 1988, 2007), (19, 1988, 2008), (19, 1988, 2009), (18, 1988, 2010), (18, 1988, 2011), (16, 1988, 2012), (16, 1988, 2013), (16, 1988, 2014), (16, 1988, 2015), (16, 1988, 2016), (16, 1988, 2017), (16, 1988, 2018), (16, 1988, 2019), (16, 1988, 2020), (16, 1988, 2021), (15, 1988, 2022), (15, 1988, 2023), (13, 1988, 2024), (10, 1988, 2025), (8, 1988, 2026), (23, 1989, 1999), (23, 1989, 2000), (23, 1989, 2001), (23, 1989, 2002), (23, 1989, 2003), (22, 1989, 2004), (21, 1989, 2005), (19, 1989, 2006), (19, 1989, 2007), (19, 1989, 2008), (19, 1989, 2009), (18, 1989, 2010), (18, 1989, 2011), (16, 1989, 2012), (16, 1989, 2013), (16, 1989, 2014), (16, 1989, 2015), (16, 1989, 2016), (16, 1989, 2017), (16, 1989, 2018), (16, 1989, 2019), (16, 1989, 2020), (16, 1989, 2021), (15, 1989, 2022), (15, 1989, 2023), (13, 1989, 2024), (10, 1989, 2025), (8, 1989, 2026), (23, 1990, 2000), (23, 1990, 2001), (23, 1990, 2002), (23, 1990, 2003), (22, 1990, 2004), (21, 1990, 2005), (19, 1990, 2006), (19, 1990, 2007), (19, 1990, 2008), (19, 1990, 2009), (18, 1990, 2010), (18, 1990, 2011), (16, 1990, 2012), (16, 1990, 2013), (16, 1990, 2014), (16, 1990, 2015), (16, 1990, 2016), (16, 1990, 2017), (16, 1990, 2018), (16, 1990, 2019), (16, 1990, 2020), (16, 1990, 2021), (15, 1990, 2022), (15, 1990, 2023), (13, 1990, 2024), (10, 1990, 2025), (8, 1990, 2026), (24, 1991, 2001), (24, 1991, 2002), (24, 1991, 2003), (23, 1991, 2004), (22, 1991, 2005), (20, 1991, 2006), (20, 1991, 2007), (20, 1991, 2008), (20, 1991, 2009), (19, 1991, 2010), (19, 1991, 2011), (17, 1991, 2012), (17, 1991, 2013), (17, 1991, 2014), (17, 1991, 2015), (17, 1991, 2016), (17, 1991, 2017), (17, 1991, 2018), (17, 1991, 2019), (17, 1991, 2020), (17, 1991, 2021), (16, 1991, 2022), (16, 1991, 2023), (14, 1991, 2024), (11, 1991, 2025), (9, 1991, 2026), (25, 1992, 2002), (25, 1992, 2003), (24, 1992, 2004), (23, 1992, 2005), (21, 1992, 2006), (21, 1992, 2007), (21, 1992, 2008), (21, 1992, 2009), (20, 1992, 2010), (20, 1992, 2011), (18, 1992, 2012), (18, 1992, 2013), (18, 1992, 2014), (18, 1992, 2015), (18, 1992, 2016), (18, 1992, 2017), (18, 1992, 2018), (18, 1992, 2019), (18, 1992, 2020), (18, 1992, 2021), (17, 1992, 2022), (17, 1992, 2023), (15, 1992, 2024), (12, 1992, 2025), (10, 1992, 2026), (25, 1993, 2003), (24, 1993, 2004), (23, 1993, 2005), (21, 1993, 2006), (21, 1993, 2007), (21, 1993, 2008), (21, 1993, 2009), (20, 1993, 2010), (20, 1993, 2011), (18, 1993, 2012), (18, 1993, 2013), (18, 1993, 2014), (18, 1993, 2015), (18, 1993, 2016), (18, 1993, 2017), (18, 1993, 2018), (18, 1993, 2019), (18, 1993, 2020), (18, 1993, 2021), (17, 1993, 2022), (17, 1993, 2023), (15, 1993, 2024), (12, 1993, 2025), (10, 1993, 2026), (24, 1994, 2004), (23, 1994, 2005), (21, 1994, 2006), (21, 1994, 2007), (21, 1994, 2008), (21, 1994, 2009), (20, 1994, 2010), (20, 1994, 2011), (18, 1994, 2012), (18, 1994, 2013), (18, 1994, 2014), (18, 1994, 2015), (18, 1994, 2016), (18, 1994, 2017), (18, 1994, 2018), (18, 1994, 2019), (18, 1994, 2020), (18, 1994, 2021), (17, 1994, 2022), (17, 1994, 2023), (15, 1994, 2024), (12, 1994, 2025), (10, 1994, 2026), (27, 1995, 2005), (25, 1995, 2006), (25, 1995, 2007), (25, 1995, 2008), (25, 1995, 2009), (24, 1995, 2010), (24, 1995, 2011), (22, 1995, 2012), (22, 1995, 2013), (22, 1995, 2014), (22, 1995, 2015), (22, 1995, 2016), (22, 1995, 2017), (22, 1995, 2018), (22, 1995, 2019), (22, 1995, 2020), (22, 1995, 2021), (21, 1995, 2022), (21, 1995, 2023), (18, 1995, 2024), (14, 1995, 2025), (10, 1995, 2026), (25, 1996, 2006), (25, 1996, 2007), (25, 1996, 2008), (25, 1996, 2009), (24, 1996, 2010), (24, 1996, 2011), (22, 1996, 2012), (22, 1996, 2013), (22, 1996, 2014), (22, 1996, 2015), (22, 1996, 2016), (22, 1996, 2017), (22, 1996, 2018), (22, 1996, 2019), (22, 1996, 2020), (22, 1996, 2021), (21, 1996, 2022), (21, 1996, 2023), (18, 1996, 2024), (14, 1996, 2025), (10, 1996, 2026), (25, 1997, 2007), (25, 1997, 2008), (25, 1997, 2009), (24, 1997, 2010), (24, 1997, 2011), (22, 1997, 2012), (22, 1997, 2013), (22, 1997, 2014), (22, 1997, 2015), (22, 1997, 2016), (22, 1997, 2017), (22, 1997, 2018), (22, 1997, 2019), (22, 1997, 2020), (22, 1997, 2021), (21, 1997, 2022), (21, 1997, 2023), (18, 1997, 2024), (14, 1997, 2025), (10, 1997, 2026), (25, 1998, 2008), (25, 1998, 2009), (24, 1998, 2010), (24, 1998, 2011), (22, 1998, 2012), (22, 1998, 2013), (22, 1998, 2014), (22, 1998, 2015), (22, 1998, 2016), (22, 1998, 2017), (22, 1998, 2018), (22, 1998, 2019), (22, 1998, 2020), (22, 1998, 2021), (21, 1998, 2022), (21, 1998, 2023), (18, 1998, 2024), (14, 1998, 2025), (10, 1998, 2026), (25, 1999, 2009), (24, 1999, 2010), (24, 1999, 2011), (22, 1999, 2012), (22, 1999, 2013), (22, 1999, 2014), (22, 1999, 2015), (22, 1999, 2016), (22, 1999, 2017), (22, 1999, 2018), (22, 1999, 2019), (22, 1999, 2020), (22, 1999, 2021), (21, 1999, 2022), (21, 1999, 2023), (18, 1999, 2024), (14, 1999, 2025), (10, 1999, 2026), (24, 2000, 2010), (24, 2000, 2011), (22, 2000, 2012), (22, 2000, 2013), (22, 2000, 2014), (22, 2000, 2015), (22, 2000, 2016), (22, 2000, 2017), (22, 2000, 2018), (22, 2000, 2019), (22, 2000, 2020), (22, 2000, 2021), (21, 2000, 2022), (21, 2000, 2023), (18, 2000, 2024), (14, 2000, 2025), (10, 2000, 2026), (24, 2001, 2011), (22, 2001, 2012), (22, 2001, 2013), (22, 2001, 2014), (22, 2001, 2015), (22, 2001, 2016), (22, 2001, 2017), (22, 2001, 2018), (22, 2001, 2019), (22, 2001, 2020), (22, 2001, 2021), (21, 2001, 2022), (21, 2001, 2023), (18, 2001, 2024), (14, 2001, 2025), (10, 2001, 2026), (22, 2002, 2012), (22, 2002, 2013), (22, 2002, 2014), (22, 2002, 2015), (22, 2002, 2016), (22, 2002, 2017), (22, 2002, 2018), (22, 2002, 2019), (22, 2002, 2020), (22, 2002, 2021), (21, 2002, 2022), (21, 2002, 2023), (18, 2002, 2024), (14, 2002, 2025), (10, 2002, 2026), (22, 2003, 2013), (22, 2003, 2014), (22, 2003, 2015), (22, 2003, 2016), (22, 2003, 2017), (22, 2003, 2018), (22, 2003, 2019), (22, 2003, 2020), (22, 2003, 2021), (21, 2003, 2022), (21, 2003, 2023), (18, 2003, 2024), (14, 2003, 2025), (10, 2003, 2026), (22, 2004, 2014), (22, 2004, 2015), (22, 2004, 2016), (22, 2004, 2017), (22, 2004, 2018), (22, 2004, 2019), (22, 2004, 2020), (22, 2004, 2021), (21, 2004, 2022), (21, 2004, 2023), (18, 2004, 2024), (14, 2004, 2025), (10, 2004, 2026), (22, 2005, 2015), (22, 2005, 2016), (22, 2005, 2017), (22, 2005, 2018), (22, 2005, 2019), (22, 2005, 2020), (22, 2005, 2021), (21, 2005, 2022), (21, 2005, 2023), (18, 2005, 2024), (14, 2005, 2025), (10, 2005, 2026), (22, 2006, 2016), (22, 2006, 2017), (22, 2006, 2018), (22, 2006, 2019), (22, 2006, 2020), (22, 2006, 2021), (21, 2006, 2022), (21, 2006, 2023), (18, 2006, 2024), (14, 2006, 2025), (10, 2006, 2026), (22, 2007, 2017), (22, 2007, 2018), (22, 2007, 2019), (22, 2007, 2020), (22, 2007, 2021), (21, 2007, 2022), (21, 2007, 2023), (18, 2007, 2024), (14, 2007, 2025), (10, 2007, 2026), (22, 2008, 2018), (22, 2008, 2019), (22, 2008, 2020), (22, 2008, 2021), (21, 2008, 2022), (21, 2008, 2023), (18, 2008, 2024), (14, 2008, 2025), (10, 2008, 2026), (22, 2009, 2019), (22, 2009, 2020), (22, 2009, 2021), (21, 2009, 2022), (21, 2009, 2023), (18, 2009, 2024), (14, 2009, 2025), (10, 2009, 2026), (22, 2010, 2020), (22, 2010, 2021), (21, 2010, 2022), (21, 2010, 2023), (18, 2010, 2024), (14, 2010, 2025), (10, 2010, 2026), (23, 2011, 2021), (22, 2011, 2022), (22, 2011, 2023), (19, 2011, 2024), (15, 2011, 2025), (10, 2011, 2026), (22, 2012, 2022), (22, 2012, 2023), (19, 2012, 2024), (15, 2012, 2025), (10, 2012, 2026), (22, 2013, 2023), (19, 2013, 2024), (15, 2013, 2025), (10, 2013, 2026), (19, 2014, 2024), (15, 2014, 2025), (10, 2014, 2026), (15, 2015, 2025), (10, 2015, 2026), (10, 2016, 2026)]

Now we can turn this new list of tuples into a DataFrame, add a column with the length of the period, and sort it by decreasing period length:

balanced_panels = pl.DataFrame(
    selected_list_n_valid,
    orient="row",
    schema=["n_valid", "period_start", "period_end"]
).with_columns(
    (pl.col("period_end") - pl.col("period_start")).alias("period_length")
).sort(
    "period_length", "n_valid", descending=True
)

balanced_panels
shape: (2_211, 4)
n_valid period_start period_end period_length
i64 i64 i64 i64
5 1954 2025 71
5 1954 2024 70
5 1955 2025 70
5 1954 2023 69
5 1955 2024 69
6 1950 1960 10
6 1951 1961 10
5 1948 1958 10
5 1947 1957 10
5 1949 1959 10

If there is any trend such as a decrease in the snow pack height due to global warming, we want to include data up to the present.

Your turn:

Create a DataFrame of balanced panels similar to balanced_panels but in which all periods include the present.

Call it current.

To print more rows than the default, you can use polars.Config.set_tbl_rows:

with pl.Config(tbl_rows=100):
    balanced_current

48 seasons for 8 stations is not bad, so let’s select the period from 1978 to the present and create a new DataFrame called subset_df:

subset_df = season_data.filter(
    pl.col("season").is_between(1978, 2026)
)

subset_df
shape: (6_261, 7)
station elevation date snow water range season
str i64 date f64 f64 str i32
"Mount Wells" 1490 1978-02-27 112.0 310.0 "Vancouver Island" 1978
"Mount Wells" 1490 1978-03-28 127.0 358.0 "Vancouver Island" 1978
"Mount Wells" 1490 1978-04-26 124.0 404.0 "Vancouver Island" 1978
"Mount Wells" 1490 1978-05-31 56.0 198.0 "Vancouver Island" 1978
"Mount Wells" 1490 1979-02-26 160.0 495.0 "Vancouver Island" 1979
"Mount Sheba" 1490 2022-12-30 112.0 301.0 "Sea to Sky" 2023
"Mount Sheba" 1490 2023-02-01 null null "Sea to Sky" 2023
"Mount Sheba" 1490 2023-02-28 225.0 715.0 "Sea to Sky" 2023
"Mount Sheba" 1490 2023-03-30 206.0 794.0 "Sea to Sky" 2023
"Mount Sheba" 1490 2023-04-28 208.0 853.0 "Sea to Sky" 2023

Now we want to get a list of the stations that have data for all seasons between 1978 and the present:

max_n_seasons = subset_df.group_by("station").agg(
    pl.col("season").n_unique().alias("n_seasons")
).select(pl.col("n_seasons")).max().item()

subset_stations = subset_df.group_by("station").agg(
    pl.col("season").n_unique().alias("n_seasons")
).filter(pl.col("n_seasons") == max_n_seasons).get_column("station").to_list()

print(len(subset_stations))  # should return 8
print(subset_stations)
8
['Klesilkwa', 'Grouse Mountain', 'Duffey Lake', 'Wolf River Lower', 'Mount Wells', 'Forbidden Plateau', 'Upper Thelwood Lake', 'Nahatlatch River']

Finally, we filter data for those stations:

subset_data = subset_df.filter(pl.col("station").is_in(subset_stations))

subset_data
shape: (1_675, 7)
station elevation date snow water range season
str i64 date f64 f64 str i32
"Mount Wells" 1490 1978-02-27 112.0 310.0 "Vancouver Island" 1978
"Mount Wells" 1490 1978-03-28 127.0 358.0 "Vancouver Island" 1978
"Mount Wells" 1490 1978-04-26 124.0 404.0 "Vancouver Island" 1978
"Mount Wells" 1490 1978-05-31 56.0 198.0 "Vancouver Island" 1978
"Mount Wells" 1490 1979-02-26 160.0 495.0 "Vancouver Island" 1979
"Klesilkwa" 1175 2025-02-26 14.0 50.0 "Cascades" 2025
"Klesilkwa" 1175 2025-03-30 5.0 18.0 "Cascades" 2025
"Klesilkwa" 1175 2025-04-29 0.0 0.0 "Cascades" 2025
"Klesilkwa" 1175 2025-12-31 48.0 106.0 "Cascades" 2026
"Klesilkwa" 1175 2026-01-27 22.0 71.0 "Cascades" 2026

subset_data is a balanced panel of 8 stations between 1978 and 2026. That’s the data we will plot and play with.

Add ENSO data

The Pacific coast is strongly affected by El Niño–Southern Oscillation (ENSO)—an unpredictable pseudo-cycle of sea-surface temperature changes that lead to atmospheric oscillations. El Niño years tend to be drier and warmer, so bad for the snowpack (and skiers!) while La Niña tend to be wetter and colder (so great for non-skiers but bad for the snowpack and skiers).

Below a list of El Niño and La Niña years for our period of interest. It comes from the National Oceanic and Atmospheric Administration Oceanic Niño Index (ONI) data. Years that don’t fall under either El Niño or La Niña are considered “neutral”.

This tells a simplified story because not all El Niño or La Niña years are the same: there are strong, moderate, and weak events in which the patterns observed during El Niño or La Niña have different intensities.

el_nino_years = [
    1978, 1980, 1983, 1987, 1988, 1992, 1995, 1998, 2003,
    2005, 2007, 2010, 2015, 2016, 2019, 2020, 2024
]

la_nina_years = [
    1984, 1985, 1989, 1996, 1999, 2000, 2001, 2006, 2008, 2009,
    2011, 2012, 2017, 2018, 2021, 2022, 2023, 2025, 2026
]

We can add a column for ENSO data to our DataFrame (note the use of polars.when, polars.then, polars.otherwise, polars.is_in, and polars.lit in this snippet):

subset_enso = subset_data.with_columns(
    pl.when(pl.col("season").is_in(el_nino_years)).then(pl.lit("El Niño"))
    .when(pl.col("season").is_in(la_nina_years)).then(pl.lit("La Niña"))
    .otherwise(pl.lit("Neutral"))
    .alias("enso")
)

subset_enso
shape: (1_675, 8)
station elevation date snow water range season enso
str i64 date f64 f64 str i32 str
"Mount Wells" 1490 1978-02-27 112.0 310.0 "Vancouver Island" 1978 "El Niño"
"Mount Wells" 1490 1978-03-28 127.0 358.0 "Vancouver Island" 1978 "El Niño"
"Mount Wells" 1490 1978-04-26 124.0 404.0 "Vancouver Island" 1978 "El Niño"
"Mount Wells" 1490 1978-05-31 56.0 198.0 "Vancouver Island" 1978 "El Niño"
"Mount Wells" 1490 1979-02-26 160.0 495.0 "Vancouver Island" 1979 "Neutral"
"Klesilkwa" 1175 2025-02-26 14.0 50.0 "Cascades" 2025 "La Niña"
"Klesilkwa" 1175 2025-03-30 5.0 18.0 "Cascades" 2025 "La Niña"
"Klesilkwa" 1175 2025-04-29 0.0 0.0 "Cascades" 2025 "La Niña"
"Klesilkwa" 1175 2025-12-31 48.0 106.0 "Cascades" 2026 "La Niña"
"Klesilkwa" 1175 2026-01-27 22.0 71.0 "Cascades" 2026 "La Niña"

Plotting

Let’s load the seaborn library:

import seaborn as sns

There are several ways to plot in seaborn. In this course, we will use the functions that plot across seaborn.FacedGrid.

Relationship plots

seaborn.relplot displays relationships between dependent and independent variables.

Scatter plots

To display the relationship between the height of snow and the season, you could first calculate the mean height of the snowpack for each season:

season_means = subset_enso.group_by(
    pl.col("season"),
    maintain_order=True
).agg(
    pl.col("snow").mean().alias("mean_snow")
)

Then plot those means against the seasons:

sns.relplot(
    data=season_means,
    x="season",
    y="mean_snow"
).figure.set_size_inches(8, 4)

In Jupyter, the plots will be displayed automatically. Outside Jupyter, you need to import matplotlib.pyplot and run matplotlib.pyplot.show():

import matplotlib.pyplot as plt
plt.show()

Line plots

By default kind is set to scatter and uses under the hood the function season.scatterplot.

You can change it to line and it will use instead the function seaborn.lineplot:

sns.relplot(
    data=season_means,
    kind="line",
    x="season",
    y="mean_snow"
).figure.set_size_inches(8, 4)

But calculating the mean manually as we just did isn’t necessary with seaborn which is a statistically oriented plotting framework. You can directly plot the height of the snowpack against the seasons and seaborn will calculate and plot the mean and 95% confidence interval around the mean:

sns.relplot(
    data=subset_enso,
    kind="line",
    x="season",
    y="snow"
).figure.set_size_inches(8, 4)

We can see that there is a great deal of year to year variation in the snowpack height, but it doesn’t look like there is much of a trend in the height of the snowpack over time.

To assess this further, we can use regression plots.

Regression plots

seaborn.lmplot plots the data and a linear regression model fit:

sns.lmplot(
    data=subset_enso,
    x="season",
    y="snow"
).figure.set_size_inches(8, 4)

Note that you can overlay multiple plots, as long as they share the same axis, by running them in the cell Jupyter cell or, if outside Jupyter, calling them before calling matplotlib.pyplot.show(). In our case, the result is very busy and not great however:

sns.relplot(
    data=subset_enso,
    kind="line",
    x="season",
    y="snow"
).figure.set_size_inches(8, 4)

sns.lmplot(
    data=subset_enso,
    x="season",
    y="snow"
).figure.set_size_inches(8, 4)

You can get the regression lines across various categories by passing a categorical variable to the hue argument:

sns.lmplot(
    data=subset_enso,
    x="season",
    y="snow",
    hue="enso"
).figure.set_size_inches(8, 4)

It looks like there is a downward trend for El Niño years.

Your turn:

Create relationship and regression plots for the El Niño data only.

They should look like the following:

Your turn:

Now make the same regression plot with only the stations below 1100m to see whether climate change is affecting low elevations more strongly.

Does it look like they are?

Categorical data

Categorical data can be displayed thanks to season.catplot.

Categorical scatterplots

By default, catplot displays a cloud of markers for each category:

sns.catplot(
    data=subset_enso,
    x="enso",
    y="snow",
    order=["La Niña", "Neutral", "El Niño"]
).figure.set_size_inches(8, 4)

Boxplots

Boxplots are a good way to display differences between groups. They can be draw in seaborn by passing box to the kind argument (the default is strip):

sns.catplot(
    data=subset_enso,
    x="enso",
    y="snow",
    kind="box",
    order=["La Niña", "Neutral", "El Niño"]
).figure.set_size_inches(8, 4)

Violin plots

For violin plots, pass violin to kind:

sns.catplot(
    data=subset_enso,
    x="enso",
    y="snow",
    kind="violin",
    order=["La Niña", "Neutral", "El Niño"]
).figure.set_size_inches(8, 4)

Distributions

seaborn.displot allows to display distribution plots.

Histograms

By default displot draws histograms (the default for the kind argument is hist and it uses seaborn.histplot under the hood):

sns.displot(
    data=subset_enso,
    x="snow",
    hue="enso"
).figure.set_size_inches(8, 4)

We can see that there is more data in the left bins for El Niño and more in the right bins for La Niña but it is not the best plot to tell our story.

Kernel density estimation

Kernel density estimation (KDE) applies kernel smoothing to the probability density estimation. You can plot them by passing kde to the kind argument (it uses seaborn.kdeplot under the hood).

The value for cut sets how far the evaluation grid extends past the extreme data points. Its default is 3. Setting it to 0 prevents it from drawing negative height of snow by going below zero:

sns.displot(
    data=subset_enso,
    x="snow",
    hue="enso",
    kind="kde",
    cut=0
).figure.set_size_inches(8, 4)

This is even worse than the histogram to show tell our story. It is not a great plot with our data.

eCDF plots

Empirical cumulative distribution functions (eCDF) display the fraction of observations that are smaller or equal to the values on the x axis.

This can be achieved by passing the value ecdf in the kind argument of the displot (which uses seaborn.ecdfplot under the hood):

sns.displot(
    data=subset_enso,
    x="snow",
    hue="enso",
    kind="ecdf"
).figure.set_size_inches(8, 4)

This is a much better way to display this data as it clearly tells the story: we can see that La Niña have a higher snowpack than neutral years which are in turn better than El Niño years.

References

1.
Waskom ML (2021) Seaborn: Statistical data visualization. Journal of Open Source Software 6(60):3021. https://doi.org/10.21105/joss.03021