4

I'm trying to do an example of trig modelling. Very simple, but hoping to use real data. I can get weather data for where I live here, and it makes a pretty reasonable sinusoid

    DateListPlot[
 WeatherData["Edmonton", 
  "MeanTemperature", {{2005, 1, 1}, {2011, 12, 31}, "Month"}], 
 Joined -> True]

weather data

I am looking for a VERY SIMPLE overlay of an actual sine graph, period would be 1 year, I'm guessing the midline would be about 5 degrees, amplitude is about 15 degrees, and phase shift is 0.

This is just as much a math question as a Mathematica question. Like I said, I don't need a trig regression, at least not for this example. Just want to illustrate the process to my students, approximate a, b, c and d in the general equation y = a + b sin c(x-d) to show them a transformation of a function to reasonably match this data. If I find a plot that is reasonable, how do I overlay the two graphs?

Also, I figured sunrise or sunset times would have been a better source of data, but didn't see anyway to access that from MMA, though I could get it from Alpha.

Yes, this is non-math major, non-Mathematica expert , lame question! But help is appreciated.

Okay, with help from @b.gatessucks I have made some progress, though I still value any feedback or help. So I get the weather data

data = WeatherData["Edmonton", 
   "MeanTemperature", {{2005, 1, 1}, {2011, 12, 31}, "Month"}];

changed the list to a numerical form, where the first entry is the number of seconds since Jan. 1 , 1900

newdata1 = {AbsoluteTime[#[[1]]], #[[2]]} & /@ data

I wanted this graph to have more reasonable numbers to use as an example with high school students, so I got the number of seconds up to Jan. 1, 2005 (where my data starts)

t1 = AbsoluteTime[{2005, 1, 1, 0, 0, 0}] 

and subtract this from every entry so our time scale now has 0 at Jan. 1, 2005

newdata2 = {#[[1]] - t1, #[[2]]} & /@ newdata1

Now take that and divide by the number of seconds in year since I'd like each 1 on the time axis to represent 1 year

year = 3.154 10^7
newdata3 = {#[[1]]/year, #[[2]]} & /@ newdata2

This gives this plot

list plot

Which now lets me write a sin function using "reasonable" numbers. Note, I know this isn't a "fit" , it was intended to be more of a visual exercise in transformations of sine function.

enter image description here

Show[ListPlot[newdata3, Joined -> True], 
 Plot[2 + 15 Sin[2 \[Pi] (x - 0.25)], {x, 0, 7}, PlotStyle -> Dashed],
  PlotRange -> {{-1, 7}, {-15, 20}}, ImageSize -> 300]
J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Tom De Vries
  • 3,758
  • 18
  • 36

2 Answers2

3

You can make a fit to your data by converting dates to their numerical value. The following is a starting point :

data = WeatherData["Edmonton", "MeanTemperature", {{2005, 1, 1}, {2011, 12, 31}, "Month"}] ;

nlm = NonlinearModelFit[{AbsoluteTime[#[[1]]], #[[2]]} & /@ data, a + b Sin[c (t - d)], {a, b, c, d}, t, Method -> {NMinimize}];

DateListPlot[{data, {#[[1]], nlm[#[[1]] // AbsoluteTime]} & /@ data}, Joined -> True]

plot

You can find some suggestions about improving your fit here.

b.gates.you.know.what
  • 20,103
  • 2
  • 43
  • 84
3

As to using sunrise data: Using AstronomicalData you have that at your fingertips.

AstronomicalData[
   "Sun", 
   {"NextRiseTime", {2012, 11, 4}, CityData[{"Edmonton", "USA"}, "Coordinates"]}, 
   TimeZone -> -6
]

{2012, 11, 4, 6, 10, 41.507}

Your TimeZone may be one hour off depending on whether or not you are observing DST. It has been changed today I believe.

DateListPlot[
  Table[
    {#, AstronomicalData[
          "Sun", 
          {"NextRiseTime", #, CityData[{"Edmonton", "USA"}, "Coordinates"]}, 
          TimeZone -> -6
        ].{0, 0, 0, 1, 1/60, 1/3600}
    } &[DatePlus[{2005, 1, 1}, {d, "Day"}]], 
 {d, 0, 5*365, 10}],
 Joined -> True
 ]

Mathematica graphics

Sjoerd C. de Vries
  • 65,815
  • 14
  • 188
  • 323
  • Sweet! I figured that would be very, very symmetrical. I read through AstronomicalData but just didn't see that. Nice! – Tom De Vries Nov 05 '12 at 00:31