4
$\begingroup$

My graph is about fires (burned area) over 12 years presented in one Date List Log Plot. Because most of fires are in summer (as expected) I would like to highlight that with different background colors. How can I paint seasons in Date List Plot in different colors? I want to put different background color for winter, spring... Thank you!

$\endgroup$
4
  • $\begingroup$ You can put a coloured Rectangle in the Prolog option. $\endgroup$
    – Szabolcs
    Mar 11, 2013 at 21:24
  • $\begingroup$ @Szabolcs I was writing a comment in your answer. It took me too long (more than one hour!) because I was interrupted many times by stupid things like work. Now I wonder if non-posted comments to deleted answers are second class citizens of this universe or are just kept in a wormhole until the Schröedinger's cat takes a nap. $\endgroup$ Mar 12, 2013 at 0:25
  • $\begingroup$ @belisarius I'm sorry, I didn't know. Do you need me to undelete it? Verbeia's answer was a bit more detailed then mine and I didn't want to keep both ... $\endgroup$
    – Szabolcs
    Mar 12, 2013 at 1:10
  • $\begingroup$ @Szabolcs Nahhh .. Let's the wormhole got filled up. $\endgroup$ Mar 12, 2013 at 1:21

3 Answers 3

9
$\begingroup$

I would suggest using Prolog and graphics rectangles like this

fakedata = 
  Transpose[{DatePlus[{1977, 1}, {#, "Month"}] & /@ 
     Range[0, 33*12 - 2], 
    FoldList[#1 + #2 &, 59.5, 
     RandomVariate[NormalDistribution[0.002, 0.5], 33*12 - 2]]}];

You don't need AbsoluteTime to define the dimensions of the rectangles, but you do need to define the vertical range of the rectangles to be beyond the range of your data. You can't use Scaled in just one dimension. The code below shows how to have multiple rectangles, though in this case I have used recessions and milder economic downturns in Australia rather than summers as the dates for the rectangles. (I happened to have a similar graph lying around.) If you want different colors for the different rectangles, just intersperse the colors in between the Rectangle objects in the list.

DateListPlot[fakedata, Joined -> True, 
 Prolog -> {GrayLevel[0.8], 
   Rectangle[{{1981, 6}, 0}, {{1983, 7}, 90}], 
  Rectangle[{{1989, 11}, 0}, {{1992, 3}, 90}], 
   Rectangle[{{2008, 1}, 0}, {{2009, 7}, 90}]}]

enter image description here

$\endgroup$
2
  • $\begingroup$ Thank you very much! You saved me! $\endgroup$
    – danijel
    Mar 11, 2013 at 21:47
  • $\begingroup$ @Danijel, if this answered your question, you might consider accepting the answer ;). $\endgroup$
    – Nick
    May 6, 2014 at 10:54
4
$\begingroup$

Here is the version I use (it is quite similar to Verbeia's, but I don't want to compute the vertical range every time):

ClearAll[dateListPlotShaded];
Options[dateListPlotShaded] = 
  Join[DeleteCases[Options[DateListPlot], GridLines -> _], 
        {GridLines -> None, ShadeColor -> LightBlue, ShadeOpacity -> 1}];

With[{opt = First /@ Options[DateListPlot]},
  dateListPlotShaded[ddata_, ShadeDates_, OptionsPattern[]] :=
     Module[{yRange, yPadding},
        With[{plot=DateListPlot[ddata, Sequence@@((#->OptionValue[#])& /@ opt)]},
           yRange= Last[PlotRange/.AbsoluteOptions[plot, PlotRange]];
           yPadding = If[OptionValue[Frame] === True, - .2 Subtract@@yRange, 0];                                
           Show[plot,
             Prolog -> {{OptionValue[ShadeColor], 
               Opacity[OptionValue[ShadeOpacity]], 
                 (Rectangle[
                    {AbsoluteTime[#[[1]]], 
                       yRange[[1]] - yPadding}, 
                    {AbsoluteTime[#[[2]]], 
                       yRange[[2]] + yPadding}
                    ]&) /@ ShadeDates}, 
             {OptionValue[Prolog]}}]]]];

Plotting the data:

fakedata = 
  Transpose[{DatePlus[{1977, 1}, {#, "Month"}] & /@ 
    Range[0, 33*12 - 2], 
    FoldList[#1 + #2 &, 59.5, 
    RandomVariate[NormalDistribution[0.002, 0.5], 33*12 - 2]]}];

dateListPlotShaded[fakedata, {{{1981, 6}, {1983, 7}}, {{1989, 11}, {1992, 3}}, 
   {{2008, 1}, {2009, 7}}}, Joined -> True]

enter image description here

You can use dateListPlotShaded with all the options of DateListPlot (including Prolog and with Frame -> False).

$\endgroup$
1
  • $\begingroup$ Little bit to much for my poor knowledge of programming but I will bookmark this for one day when I will be better and smarter! Thank you for your help! $\endgroup$
    – danijel
    Mar 13, 2013 at 21:00
2
$\begingroup$

Here's another suggestion - there are (at least) two caveats:

  1. you need rather dense data (I fill points from axis, so not really good for only single points in a year)
  2. I can't get it working for DateListPlot

Nevertheless, it looks quite ok to do that sort of coloring for e.g. financial data. And maybe it helps you with your fires.

So in that sense, we can load:

data = FinancialData["IBM", "Jan. 1, 2004"];

And then, we define colors per month (group of months):

setup = {{{11, 12, 1}, ColorData["SolarColors"][1/3]}, 
{{2, 3, 4}, ColorData["SolarColors"][2/3]}, 
{{5, 6, 7}, ColorData["SolarColors"][3/3]}, 
{{8, 9, 10}, ColorData["SolarColors"][0/3]}};

Then:

DateListPlot[data, Joined -> True, 
    ColorFunction -> ((Which[MemberQ[setup[[1, 1]], #], setup[[1, 2]], 
    MemberQ[setup[[2, 1]], #], setup[[2, 2]], 
    MemberQ[setup[[3, 1]], #], setup[[3, 2]], 
    MemberQ[setup[[4, 1]], #], setup[[4, 2]]] &)@
    ToExpression@DateString[#1, "Month"] &), Filling -> Axis, 
    ColorFunctionScaling -> False, ImageSize -> Large]

and get:

enter image description here

$\endgroup$
2
  • $\begingroup$ Thank you! This is also helpfull fo rsome of my graphs! $\endgroup$
    – danijel
    Mar 13, 2013 at 20:58
  • $\begingroup$ @danijel: you are welcome! $\endgroup$ Mar 13, 2013 at 21:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.