Message Boards Message Boards

It's Ridiculously Cold Outside. Let's Graph It.

Posted 7 years ago

I'm in Chicago and this past week has been brutally cold. I decided it would be fun to see just how bad it is by visualizing this year's temperatures against previous years. The results were good and I thought I'd share.

enter image description here

First, we get about 60 years of temperature data. This data has some Missing values in it, but our code will handle this problem automagically:

temps = WeatherData["Chicago" , "MeanTemperature", {{1950, 1, 1}, Today, "Day"},  "DateNonMetricValue"]

I've also asked for the values in Fahrenheit instead of the the default Celsius. You can just remove "DateNonMetricValue" if you don't like that.

Making this data into a DataSet will help us efficiently manipulate it. We want to group all the temperatures by Month and Day so we can calculate things like the Mean and Max temperatures for any given day of the year.

tempDataset = Dataset@Normal@temps;

groupedByMonthDay = 
    tempDataset[GroupBy[First /* (DateValue[#, { "Month", "Day"}] &)]]

enter image description here

Let's select just the list of temperatures for each Day:

groupedByMonthDayTemps = groupedByMonthDay[All, All, 2]

Now we can look at the Mean temperature for each day by evaluating:

groupedByMonthDayTemps[All, Mean]

We are going to reduce the list temperatures for each day with several different ways, so let's make a function out this. It will take a reducing function like Mean and apply it to each day's list of temperatures.

tempsReducedBy[transform_] := groupedByMonthDayTemps[All, transform];

I want to look at the median temperatures as well as the minimum, maximum, and upper and lower quartiles. The functions that do this are:

reductionFunctions =  {Min, Max, Median, Quantile[#, 3/4] &, Quantile[#, 1/4] &};

We can get the daily minimum temperatures and other values using them:

 {minTemps, maxTemps, medianTemps, upperQTemps, lowerQTemps} = 
      tempsReducedBy /@ reductionFunctions

Unfortunately, when we plot these, we see they are kinda bumpy:

ListPlot@minTemps[Values]

enter image description here

I just just want a general curve showing what the minimum temperatures are like. We need to smooth these out. There's a lot of ways to do this. I at first chose to use the Fourier Transform myself, but realized there's a function for LowPass Filtering:

filterTemps[temps_] := 
 LowpassFilter[Normal@temps[[Values]], 1/20, 80, HammingWindow, 
  Padding -> "Periodic"]

The values here are admittedly just magic numbers I've picked for aesthetic reasons. Let's add this to our code:

{minTemps, maxTemps, medianTemps, upperQTemps, lowerQTemps} = 
  Map[filterTemps@*tempsReducedBy, reductionFunctions];

If we plot these together, we get a good a good background for how much the temperature varies throughout the year. The code is a bit long because I got picky about how I wanted it to look:

background = DateListPlot[{
   Callout[minTemps, "Likely Record Low"],
   Callout[maxTemps, "Likely Record High"],
   Callout[medianTemps, "Median"],
   Callout[upperQTemps, "Upper Quartile"],
   Callout[lowerQTemps, "Lower Quartile"]}, {{2016, 1, 1}, Automatic,  "Day"}, 
    Joined -> True, PlotStyle -> Gray, FrameLabel -> Automatic,
   FrameTicks -> {Table[{2016, i, 1}, {i, 12}], Automatic}, 
  Axes -> False]

enter image description here

Let's get this years temperatures and lay it over our background:

currentTemps = 
    WeatherData[city, "MeanTemperature", {{2016, 1, 1}, Today, "Day"}, "DateNonMetricValue"];

thisYear = 
 DateListPlot[currentTemps, Joined -> True, PlotStyle -> Darker@Red]

enter image description here

And let's lay it on top of our background:

Show[background, thisYear, 
PlotLabel -> Style["Daily Mean Temperature - Chicago - 2016", Large, FontFamily -> "Times"]]

enter image description here

So, it's certifiably ridiculously cold in Chicago. And yesterday was almost record breaking.

Here are some graphs for other cities that like to complain about the cold. As we can conclusively see, my friends from other cities should stop complaining about how cold it is outside. Chicago has it far worse right now:

enter image description here

enter image description here

POSTED BY: Sean Clarke
3 Replies

enter image description here - you have earned "Featured Contributor" badge, congratulations !

This is a great post and it has been selected for the curated Staff Picks group. Your profile is now distinguished by a "Featured Contributor" badge and displayed on the "Featured Contributor" board.

POSTED BY: Moderation Team

Being from Rochester, NY, I'm partial to those values.

enter image description here

But, I find that lacking as it does not give a sense of the size of the data sets being used. To give a better sense of the history, I like to plot the other years as faded in the background behind the current year. So, we first need to modify the data a bit

tempsByYear = GroupBy[temps, #[[1, 1]] &];

which we can then use in DateListPlot

allData =
 DateListPlot[
  KeyValueMap[Tooltip[#2, #1] &, tempsByYear], 
  PlotStyle -> ({Opacity[
        If[# == 65, 1, 0.4 (#/Length[tempsByYear])^35 + 0.02]], 
       Darker@Red} & /@ Range[Length[tempsByYear]]), 
  DateFunction -> ({2016}~Join~Rest[#] &)];

where I added a Tooltip and used DateFunction to push everything into a common year. When combined with the background, as before, you get

enter image description here

POSTED BY: Robert Collyer

Very nice!!! We have a colder summer start, but if it follows the same as last summer, it will be warmer soon:

enter image description here

Note: I'm using Celsius.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract