Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am trying to set a graph to show the value of the equity of an investment based on whether the portfolio is invested or in cash. I tried using the ColorFunction, but was not successful. Here is the sample data.

colorCash = RGBColor[90/255, 180/255, 172/255];
colorInvested = RGBColor[216/255, 179/255, 101/255];
invested = {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            0, 1, 0, 0, 0, 0};

period = {
   {2005, 7, 1}, {2005, 8, 1}, {2005, 9, 1}, {2005, 10, 3}, {2005, 11, 1}, {2005, 12, 1},
   {2006, 1, 3}, {2006, 2, 1}, {2006, 3, 1}, {2006, 4, 3}, {2006, 5, 1}, {2006, 6, 1},
   {2006, 7, 3}, {2006, 8, 1}, {2006, 9, 1}, {2006, 10, 2}, {2006, 11, 1}, {2006, 12, 1},
   {2007, 1, 3}, {2007, 2, 1}, {2007, 3, 1}, {2007, 4, 2}, {2007, 5, 1}, {2007, 6, 1},
   {2007, 7, 2}, {2007, 8, 1}, {2007, 9, 4}, {2007, 10, 1}, {2007, 11, 1}, {2007, 12, 3},
   {2008, 1, 2}, {2008, 2, 1}, {2008, 3, 3}, {2008, 4, 1}, {2008, 5, 1}, {2008, 6, 2},
   {2008, 7, 1}, {2008, 8, 1}, {2008, 9, 2}, {2008, 10, 1}, {2008, 11, 3}, {2008, 12, 1},
   {2009, 1, 2}, {2009, 2, 2}, {2009, 3, 2}, {2009, 4, 1}, {2009, 5, 1}, {2009, 6, 1},
   {2009, 7, 1}, {2009, 8, 3}, {2009, 9, 1}, {2009, 10, 1}, {2009, 11, 2}, {2009, 12, 1},
   {2010, 1, 4}, {2010, 2, 1}, {2010, 3, 1}, {2010, 4, 1}, {2010, 5, 3}, {2010, 6, 1},
   {2010, 7, 1}, {2010, 8, 2}, {2010, 9, 1}, {2010, 10, 1}, {2010, 11, 1}, {2010, 12, 1},
   {2011, 1, 3}, {2011, 2, 1}, {2011, 3, 1}, {2011, 4, 1}, {2011, 5, 2}, {2011, 6, 1},
   {2011, 7, 1}, {2011, 8, 1}, {2011, 9, 1}, {2011, 10, 3}, {2011, 11, 1}, {2011, 12, 1},
   {2012, 1, 3}, {2012, 2, 1}, {2012, 3, 1}, {2012, 4, 2}, {2012, 5, 1}, {2012, 6, 1}};

equity = {100, 100, 100, 107.60368663594471, 106.91244239631337, 113.13364055299542,
          118.84792626728114, 130.6451612903226, 129.19354838709677, 133.8709677419355,
          149.97695852534562, 147.99539170506912, 141.08294930875573, 145.52995391705065,
   143.52534562211977, 137.02764976958522, 137.02764976958522, 137.02764976958522,
   134.51650476681908, 137.964008923159, 141.4753557490608, 139.9005698998685,
   142.77349003015175, 139.47495210278947, 136.77227909133777, 136.77227909133777,
   138.2898921592307, 152.82155701480832, 163.44484849005894, 160.74224987600297,
   171.42790901157795, 190.01347178823949, 199.95071899992203, 187.95533899753534,
   180.13859223688132, 181.8017298455311, 190.01347178823949, 187.2692947339673,
   187.2692947339673, 187.2692947339673, 187.2692947339673, 187.2692947339673,
   187.2692947339673, 197.63707006655756, 200.49416055487052, 195.407673700677,
   188.89264160232702, 208.22129164826242, 197.3556899427086, 202.0525735484958,
   202.16079667305314, 213.9571172497998, 221.92233921721777, 250.29844247614417,
   232.26846992489646, 229.34644556184912, 236.85713040612634, 235.8181884103762,
   249.69239297862313, 257.3113009474577, 263.37179592266705, 249.97377310247217,
   264.2375809191255, 276.85639724250774, 287.0510155758062, 293.1115105510154,
   300.2542367717978, 281.0987437251542, 297.95990653118287, 302.7217240117045,
   329.79914977594314, 323.8901671751141, 316.011523707342, 342.6127677235285,
   384.66827392649884, 342.11494135056495, 362.2011532684015, 368.24000361869935,
   328.9766540293077, 328.9766540293077, 319.22257687363395, 319.22257687363395,
   319.22257687363395, 319.22257687363395};

The following charts show the value of the portfolio and whether I am an investor or not:

Column[{
        DateListPlot[Transpose[{period, equity}], Filling -> Axis, 
          Joined -> True, ImageSize -> Large], 
        DateListPlot[Transpose[{period, invested}], Filling -> Axis, 
          ImageSize -> Large]
}]

This is what I tried to change the color, but it is not the correct thing to do as the period painted does not coincide with the investment period:

myColor = If[# == 1, colorInvested, colorCash] & /@ invested;

DateListPlot[Transpose[{period, equity}], Filling -> Axis, 
 Joined -> True, ColorFunction -> myColor, ImageSize -> Large]
share|improve this question
add comment

4 Answers 4

up vote 9 down vote accepted

ColorFunction is usually supposed to be a function rather than a list of colours. Unfortunately for a DateListPlot it only seems to give you the y-coordinate as input and not the x-coordinate (i.e. the date). If you give it a list instead of a function, it will colour based on height, e.g.:

DateListPlot[Transpose[{period, equity}], Joined -> True, Filling -> Axis,
   ColorFunction -> {Red, Blue, Green, Yellow}]

enter image description here

You could manually construct some polygons to do the filling you require:

prolog = Partition[Thread[{invested, period, equity}], 2, 1] /.
   {{i_, d1_, e1_}, {_, d2_, e2_}} -> {If[i == 0, colorCash, colorInvested],
      Polygon[{{d1, 0}, {d2, 0}, {d2, e2}, {d1, e1}}]};

DateListPlot[Transpose[{period, equity}], Joined -> True, Prolog -> prolog]

enter image description here

But you do get ugly seams between polygons.

EDIT

Fix for polygon seams as suggested by @kguler:

prolog = Partition[Thread[{invested, period, equity}], 2, 1] /.
   {{i_, d1_, e1_}, {_, d2_, e2_}} -> With[{c = If[i == 0, colorCash, colorInvested]},
   {c, EdgeForm[c], Polygon[{{d1, 0}, {d2, 0}, {d2, e2}, {d1, e1}}]}];

DateListPlot[Transpose[{period, equity}], Joined -> True, Prolog -> prolog]

enter image description here

share|improve this answer
    
I added a suggested modification of prolog that eliminates the visible polygon edges at the end of my post below. I meant to put it here as a comment, but the editing long code in the comment box was difficult. Pls feel free to use it to update your answer. If you do, I will delete that part from my post. (+1 btw) –  kguler Jun 6 '12 at 21:53
add comment

An alternative approach to using Prolog or ColorFunction is to plot the original series together with a copy in which equity value is replaced with MissingValue for in-cash periods. Using

eqdt = Transpose[{period, equity}];
opts = {Filling -> Axis,  FillingStyle -> {1 -> colorCash, 2 -> colorInvested}, 
  Joined -> True, ImageSize -> Large};

the simple approach

eqdtInv = eqdt;
eqdtInv[[Flatten@Position[invested, 0], 2]] = Missing["NotAvaiable"];
DateListPlot[{eqdt, eqdtInv}, opts]

produces plots in which single investment periods that fall between in-cash periods are not visible. One way to fix this issue is to insert data points in appropriate places, as in

eqdtInv2 = #[[2 ;;]] & /@ (Transpose[{invested, period, equity}] 
    /. {a___, {0, d1_, e1_}, {1, d2_, e2_}, {0, d3_, e3_}, b___} :> 
    {a, {0, d1, e1}, {1, d2, e2}, {1,DatePlus[d3, {-1, "Hour"}], e3}, {0, d3, e3}, b} 
    /. {0, d1_, e1_} :> {0, d1, Missing["NotAvailable"]})

Now, to compare the two approaches

Row[{DateListPlot[{eqdt, eqdtInv}, opts], Spacer[15],DateListPlot[{eqdt, eqdtInv2}, opts]}]

we get

enter image description here

share|improve this answer
add comment

I'd have done something similar to Heike's answer, with the difference of exploiting the fact that DateListPlot[] uses absolute times (i.e. the output of AbsoluteTime[] after being applied to a date list like {2005, 7, 1}) as the abscissa (note that this is in fact mentioned in the docs for DateListPlot[]):

investedFunction = Interpolation[Transpose[{AbsoluteTime /@ period, invested}],
                                 InterpolationOrder -> 1];

DateListPlot[Transpose[{period, equity}], 
             ColorFunction -> (Blend[{colorCash, colorInvested}, investedFunction[#1]] &),
             ColorFunctionScaling -> False, Filling -> Axis, Joined -> True]

colored date list plot

Note that there is no assumption here that the dates are equispaced.

share|improve this answer
add comment

If you specify a function to ColorFunction, i.e. ColorFunction -> fun, the arguments supplied to fun will be the x and y coordinates, so you could specify a colour function according to

myColor = Blend[{colorCash, colorInvested}, 
   Interpolation[Transpose[{Range[0, 1, 1/(Length[invested] - 1)], invested}]][#]] &

Then

DateListPlot[Transpose[{period, equity}], Filling -> Axis, 
 Joined -> True, ColorFunction -> myColor, ImageSize -> Large, ColorFunctionScaling -> True]

produces

Mathematica graphics

which gives the right colours for the right intervals but the transitions are a bit fuzzy.

share|improve this answer
    
Riddle me this, Batman: What's the difference between ColorFunction -> (wat[x__] := (Print[x]; Red); wat) and ColorFunction -> ((Print[##]; Red) &)? –  wxffles Jun 5 '12 at 21:36
1  
@wxffles Interesting. It seems that pure functions are treated differently from named functions. I vaguely remember that for some options you have to use pure functions and that Mathematica will complain if you use named ones, but I can't remember which ones. –  Heike Jun 5 '12 at 22:03
    
@Heike probably only in the un-birthday options –  belisarius Jun 5 '12 at 23:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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