# Problem achiving effect I want with ColorFunction

I want to create a plot showing historical annual maximum and minimum temperatures. I've figured out how to get 10 years of historical temperature data from Wolfram|Alpha. The plot below shows the highest, average high, average low, and lowest temperature during the past ten years for Austin, Tx. The problem occurs when I try to use ColorFunction to control the filling color.

The code below returns a relatively small amount of data that can be used to replicate the problem.

max = Map[#*9/5+32.&, WeatherData["KATT","MaxTemperature",{{2011,1,1},{2011,12,31},"Week"}][[All,2]]];
min = Map[#*9/5+32.&, WeatherData["KATT","MinTemperature",{{2011,1,1},{2011,12,31},"Week"}][[All,2]]];

DateListPlot[{max, min},{{2011,1,1},Automatic,"Week"},Joined->True, Filling->{1->{2}}, ColorFunction ->"Rainbow"]


I would like to have simple a vertical color gradient. Instead, the fill color is a more complicated function of the top curve and the y-axis. I can't describe it properly, but hopefully, the problem is apparent. I've tried several approached to controlling the fill color, but none of them do what I want, and most of them don't work at all.

I would ultimately like to use slightly different filling styles between the highest ever and average highest temperature, and between the average lowest and lowest ever - perhaps less opaque, and for the four plot lines to still be visible.

-
"I want the same color to appear at a particular temperature level across the plot, and the color also to be a function of y-axis (corresponding to the temperature in some understandable manner)." So, you want a vertical color gradient? –  VF1 Dec 1 '12 at 2:03
in the y direction the fill seems to Blend the two colours ColorData["Rainbow",y_top] and ColorData["Rainbow",y_bottom] instead of giving a gradient. Maybe someone else can comment whether that is intended behaviour. –  Mike Honeychurch Dec 1 '12 at 2:17
@MikeHoneychurch @GeorgeWolfe the issue at hand is that ColorFunction only looks at the points actually plotted out by DateListPlot, and so, since Filling doesn't actually sample every point between the two list plots, we'd have no way of assigning a y-dependent color value to each point in between the list plot lines. I believe there is no solution to this using the DateListPlot options. There is however, hope that we can solve this by extracting the Polygon that is made by Filling and artificially coloring that... –  VF1 Dec 1 '12 at 2:24
@MikeHoneychurch Wow. Much tricker than I thought! It seems like this is would be a common use of fill color. –  George Wolfe Dec 1 '12 at 2:27
A bit of a fix about filling is that FillingStyle -> (Sow[#] &) returns a Polygon with no significant information about where its points are. –  VF1 Dec 1 '12 at 2:28

This is more complicated than you would think is needed but I think this is what you are looking for (re: for your output)

  Overlay[{
DensityPlot[y, {x, 0, 1}, {y, 0, 100},
AspectRatio -> 2/5,
ColorFunction -> ColorData["Rainbow"],
ColorFunctionScaling -> True,
Frame -> False,
ImageSize -> {535, 235},
ImagePadding -> {{30, 5}, {30, 5}},
PlotRange -> Automatic,

DateListPlot[{max, min}, {{2011, 1, 1}, Automatic, "Week"},
AspectRatio -> 2/5,
Background -> None,
Filling -> {1 -> Top, 2 -> Bottom},
FillingStyle -> White,
GridLines -> None,
Joined -> True,
ImageSize -> {535, 235},
ImagePadding -> {{30, 5}, {30, 5}},
PlotStyle -> None]
}]


This is overlaying two plots that you should be familiar with re: how to tweek options.

-
I came up with this: Polygon[#1~Join~Reverse[#2] & @@ Reap[DateListPlot[{max, min}, {{2011, 1, 1}, Automatic, "Week"}, Joined -> True]/. Line[a_] :> (Sow[a]; Line[a])][[-1, -1]]], but then I realized that you can't color a gradient on a Graphics. I was going to use a DensityPlot, but then I saw you beat me to it. +1 –  VF1 Dec 1 '12 at 2:43
@Mike Honeychurch Thanks, Mike. That is what I want to do. –  George Wolfe Dec 1 '12 at 2:47
@VF1 there may be other ways but I couldn't think of any offhand. –  Mike Honeychurch Dec 1 '12 at 2:48

This is a followup to show how @Mike Honeychurch and @VF1 suggestions worked. I found that I needed to use three overlays to get the effect I wanted: a density plot for the color, a DateListPlot to show the plotlines, and another DateListPlot with no graphs to properly display Epilog text and other lines. I'm not completely finished with the plot, but here is how it looks so far:

To complete the story, here is how I cleaned and date aligned 10 years of temperature data from the Wolfram|Alpha:

max = WeatherData["KATT","MaxTemperature", {{2000, 1, 1}, {2011, 12, 31}, "Day"}];
max = Delete[max, Position[max[[All, 1, 2 ;; 3]], {2, 29}]]; (*drop Feb 29ths*)
max[[All, 2]] = Map[ # *9/5 + 32. & , max[[All, 2]]] (*convert to fahrenheit*)
maxtable = lineUpByDay[max]; (*date align - code below*)
avemax = Map[average, Transpose[maxtable]]; (*average by day-code below*)
maxmax = Map[maximum, Transpose[maxtable]]; (*record high by day-code below*)


Wolfram|Alpha returned data that had gaps (days without data). To create a date-aligned table I used a procedure:

lineUpByDay[list_] := Module[{days, years, temptable},
days = Union[list[[All, 1, 2 ;; 3]]];
years = Union[list[[All, 1, 1]]];
temptable = Table["", {r, Length[years]}, {c, Length[days]}];
Do[
r = Position[years, list[[i, 1, 1]]][[1, 1]];
c = Position[days, list[[i, 1, 2 ;; 3]]][[1, 1]];
temptable[[r, c]] = list[[i, 2]], {i, 1, Length[list]}];
temptable
]


And to get the average and maximum temperature for each day I mapped the following over maxtable:

average[list_] := Module[{x}, x = Cases[list, _Real]; Total[x]/Length[x]]
maximum[list_] := Module[{x}, x = Cases[list, _Real]; Max[x]]


I did something similiar with "MinTemperature" for the average low and record low. It's not clever, but fast and satisfactory.

-