%[text] # Normal Temperature Patterns
%[text] Are you curious to know what "normal" temperatures are across the U.S.? The animation below shows average daily temperatures for thousands of weather stations across the U.S. These averages are based on temperature data collected between 1981 and 2010. 
%[text] Watch what happens to temperatures across the country as the seasons progress. 
%[text] After using the "Plot animation" button to run the animation, a slider will appear below. Move the slider to go back and view portions of the animation. It may take a couple of minutes for the full animation to run. 
%[text] Temperature data from [National Oceanic and Atmospheric Administration](internal:M_C2BD8B1D).
if ~exist("allData","var") || ~exist("minNormTemp","var")
    load NormalWeather.mat allData minNormTemp maxNormTemp 
end
  %[control:button:7bd4]{"position":[1,2]}
animateNormals(1, 1, 12, 31, allData, minNormTemp, maxNormTemp);
%[text] %[text:anchor:M_C2BD8B1D] Full citation: Anthony Arguez, Imke Durre, Scott Applequist, Mike Squires, Russell Vose, Xungang Yin, and Rocky Bilotta (2010). NOAA's U.S. Climate Normals (1981-2010). NOAA National Centers for Environmental Information. DOI:10.7289/V5PN93JP \[June 10, 2022\].
%%
function p = plotNormalWeatherDay(allData,dt,minTemp,maxTemp)
clf
dayChoice = calculateDayNum(dt);
ax = geoaxes;
geobasemap(ax,"colorterrain")
byDay = allData.DayNum == dayChoice;    
daySlice = allData.HR15(byDay);
idx = isnan(daySlice);
cmAug = defineColors;
colIdx = 1 + ceil(20*(daySlice-minTemp)/(maxTemp-minTemp));
colIdx(idx) = 1;
colorChoices = cmAug(colIdx,:);
p = scatter(ax,allData.LATITUDE(byDay),allData.LONGITUDE(byDay),"filled","CData",colorChoices);
title("Normal Temperatures at 3 pm")
geolimits([15 72],[-175 -65])
c = colorbar;
c.Label.String = "Temperature (F)";
c.Limits = [0 1];
c.TickLabels = round(linspace(minTemp,maxTemp,11),1);
end

function cmAug = defineColors
cmlen = 20;
cm = parula(cmlen);
cmAug = [1 1 1; cm];
end

function dayChoice = calculateDayNum(dt)
dayChoice = days(dt-datetime(2020,12,31));
end

function [startk, endk] = findStartEnd(startMonth, startDay, endMonth, endDay)
startk = calculateDayNum(datetime(2021,startMonth,startDay));
endk = calculateDayNum(datetime(2021,endMonth,endDay));
if endk < startk
    disp("Your start date is later than your stop date, reversing the order.")
    sk = endk;
    endk = startk;
    startk = sk;
end
end

function animateNormals(startMonth, startDay, endMonth, endDay, allData, minTemp, maxTemp)
[startk, endk] = findStartEnd(startMonth, startDay, endMonth, endDay);
p = plotNormalWeatherDay(allData,datetime(2021,startMonth,startDay),minTemp,maxTemp);
cmAug = defineColors;
for k = startk:endk
    if k == startk
        drawnow
    end
    byDay = allData.DayNum == k;
    daySlice = allData.HR15(byDay);
    date = allData.dt(byDay);
    p.Parent.Subtitle.String = string(month(date(1),"name")) + " " + day(date(1));
    idx = isnan(daySlice);
    colIdx = 1 + ceil(20*(daySlice-minTemp)/(maxTemp-minTemp));
    colIdx(idx) = 1;
    p.CData = cmAug(colIdx,:);
    drawnow
end
end


%[appendix]{"version":"1.0"}
%---
%[metadata:view]
%   data: {"layout":"hidecode","rightPanelPercent":40}
%---
%[control:button:7bd4]
%   data: {"label":"Plot animation","run":"AllSections"}
%---
