14
$\begingroup$

I have been working with Sparklines, thanks to some code found here. Here is what I am using:

sparkline[data_] :=
 DateListPlot[data, {1997}, 
  FrameTicks -> {{Automatic, Automatic}, {{{2007, 1, 15}, Red}}, 
    None}, Axes -> False, Frame -> False, Joined -> True, 
  PlotRange -> All, Filling -> Bottom, AspectRatio -> 0.2, 
  ImageSize -> 120]

Here is my data:

data={{0, 0.00342768669164354`, 0.00503464769633257`, 0, 0.000187`, 0, 0, 
      0, 0, 0, 0, 0, 0, 0}, {0.0415627991238424`, 0.0545451018506565`, 
      0.0395873926886832`, 0.0284671754269643`, 0.0390903566779343`, 
      0.0344695110117644`, 0.0326128167712641`, 0.0380630684019641`, 
      0.0358499768032886`, 0.0241216221583061`, 0.0421644617338612`, 
      0.013010650199335`, 0.0249861212092993`, 0.0052690153372215`}};

I have been arranging them in charts, like so:

Grid[{{"Topic No.", "Sparkline"}, {"1", sparkline[data[[1]]]}, {"2", 
   sparkline[data[[2]]]}}, Frame -> All, 
 Background -> {None, {LightGray}}]

enter image description here

What I am trying to do, so far unsuccessful, is find options to put lines within the Sparkline to indicate a specific date. i.e. is there a way that I could add a line for the year '2005' in the example above? The beauty of the Sparkline lies in having no frame or printed axes, but most of the Mathematica commands that come to mind rely on those.

My end goal would be to have something like this (where the line is at 2005, although this is just a mock up):

enter image description here

$\endgroup$
3

4 Answers 4

13
$\begingroup$

You can use Epilog to add lines and other things to your graphs. The simplest solution would be to add it to the sparkline function, like so:

sparkline[data_] := 
 DateListPlot[data, {1997}, 
  FrameTicks -> {{Automatic, Automatic}, {{{2007, 1, 15}, Red}}, 
    None}, Axes -> False, Frame -> False, Joined -> True, 
  PlotRange -> All, Filling -> Bottom, AspectRatio -> 0.2, 
  ImageSize -> 120, 
  Epilog -> Line[{{{2005, 1, 1}, 0}, {{2005, 1, 1}, 1}}]]

Which give you:

Mathematica graphics

$\endgroup$
12
$\begingroup$

Mr Alpha's answer is correct. Epilog (or Prolog) is the right way to get such annotations onto this or any other kind of graph. One caveat, though: if you are using Epilog within the function definition to get some other effect, e.g. Tufte-style dots for minimum and maximum data points or whatever it may be, you need to make sure that the function definition you are using can incorporate both the special line you want, and the standard annotations provided in your function.

While perhaps a little complex for this illustration, here is some code I happen to have lying around that does sparkline plots, complete with a range of options.

Options[SparklinePlot] = {ShowMinMax -> True, ShowSDBar -> False, 
  LastDotColor -> Red, MinMaxColor -> Hue[0.6], 
  SDBarColor -> {GrayLevel[0.4], Opacity[0.2]}, 
  SparktextStyle -> {FontFamily -> "Gill Sans", FontSize -> 9}, 
  DateStringForm -> {"DayShort", "/", "MonthShort", "/", "YearShort"}};

SparklinePlot[dateddata : {{_List, _?NumericQ} ..}, title_String, 
 opts:OptionsPattern[{SparklinePlot,DateListPlot}]] :=
 With[{data = dateddata[[All, 2]]},
  With[{showmax = OptionValue[ShowMinMax], showsdbar = OptionValue[ShowSDBar ],
    ldcolor = OptionValue[LastDotColor], mmcolor = OptionValue[MinMaxColor],
    sdbcolor = OptionValue[SDBarColor], textstyle = OptionValue[SparktextStyle], 
    epi = OptionValue[Epilog],  datestringform =  OptionValue[DateStringForm ],
    mind = Min[data], maxd = Max[data], sd = StandardDeviation[data], ave = Mean[data]
    }, Grid[{{Graphics[
       DateListPlot[dateddata,Epilog :> {epi}~Join~{ldcolor, AbsolutePointSize[4.5], 
          Point[Last[dateddata]], 
          Sequence @@ If[showmax, {mmcolor, 
             Point[dateddata[[Position[data, mind][[1, 1]]]]], 
             Point[dateddata[[
               Position[data, maxd][[1, 1]]]]]}, {mmcolor}],        
          Sequence @@ If[showsdbar, {Sequence @@ sdbcolor, 
             Rectangle[{First[First[dateddata]], 
               ave - sd}, {First[Last[dateddata]], 
               ave + sd}]}, {mmcolor}]
          }, FilterRules[{opts}, Options[DateListPlot]], Joined -> True, Frame -> False, 
        Axes -> False,  PlotRangePadding -> {Scaled[5/Length[data]], 0.4 sd}, 
        AspectRatio -> 0.2, PlotStyle -> {GrayLevel[0], AbsoluteThickness[0.75]}, 
        ImageSize -> 150 ], ImagePadding -> 1, ImageMargins -> 0], 
      Graphics[
       Style[Text[ToString[NumberForm[Last[data], 4]]], ldcolor, 
        Sequence @@ textstyle], ImageSize -> 30, AspectRatio -> 1/4], 
      If[showmax, 
       Graphics[
        Style[Text[ToString[NumberForm[mind, 4]]], mmcolor, 
         Sequence @@ textstyle], ImageSize -> 30, AspectRatio -> 1/4],
        Graphics[Text[""], ImageSize -> 0.2]], 
      If[showmax, 
       Graphics[
        Style[Text[ToString[NumberForm[maxd, 4]]], mmcolor, 
         Sequence @@ textstyle], ImageSize -> 30, AspectRatio -> 1/4],
        Graphics[Text[""], ImageSize -> 0.2]], 
      Graphics[
       Style[Text[title], Black, TextAlignment -> Left, 
        Sequence @@ textstyle], 
       ImageSize -> Max[23, StringLength[title]*4.3], 
       AspectRatio -> 1/StringLength[title]]},
     {Graphics[
       Text[Style[DateString[First[First[dateddata]], datestringform],
          Black, TextAlignment -> Left, Sequence @@ textstyle], 
        TextAlignment -> Left], ImageSize -> 40, AspectRatio -> 1/6],
      Graphics[
       Style[Text[DateString[First[Last[dateddata]], datestringform]],
         ldcolor, Sequence @@ textstyle], ImageSize -> 40, 
       AspectRatio -> 1/6],
      If[showmax, 
       Graphics[
        Style[Text[
          DateString[First[dateddata[[Position[data, mind][[1, 1]]]]],
            datestringform]], mmcolor, Sequence @@ textstyle], 
        ImageSize -> 40, AspectRatio -> 1/4], 
       Graphics[Text[""], ImageSize -> 0.2]],
      If[showmax, 
       Graphics[
        Style[Text[
          DateString[First[dateddata[[Position[data, maxd][[1, 1]]]]],
            datestringform]], mmcolor, Sequence @@ textstyle], 
        ImageSize -> 40, AspectRatio -> 1/4], 
       Graphics[Text[""], ImageSize -> 0.2]], 
      Graphics[Text[""], ImageSize -> 0.2]}}, 
    Alignment -> {Join[{Left}, 
       If[showmax, Table[Right, {3}], Table[Right, {1}]]], 
      Join[{Left}, 
       If[showmax, Table[Right, {3}], Table[Right, {1}]], {Left}] }, 
    Spacings -> {0, -0.2}]
   ]] 

Things to note include

  • the use of both the name of this function and DateListPlot in the pattern opts:OptionsPattern[{SparklinePlot,DateListPlot}] in the function call definition;
  • catching of the OptionValue[Epilog] in the local constant epi, which is then joined to the other things defined to be in the Epilog;
  • the way the Epilog option is constructed before the other options passed to DateListPlot are actually passed. This is important so that you don't inadvertently set the Epilog option before inserting the elements defined in the body of the function definition, as opposed to passed in the function call by the user.

Here is an illustration of the function:

testdata = 
  Transpose[{DatePlus[{2000, 1}, {#, "Month"}] & /@ Range[0, 119], 
    FoldList[0.99 #1 + #2 &, 0., RandomVariate[NormalDistribution[0, 1], 119 ]]}];

SparklinePlot[testdata, "Random Series", ShowSDBar -> True, 
 Epilog -> Line[{{{2005}, -11}, {{2005}, 11}}]]

enter image description here

$\endgroup$
0
8
$\begingroup$

As an alternative why not use GridLines as per J.Ms comment.

sparkline[data_, datemarker_] := DateListPlot[data, {1997},
  AspectRatio -> 0.2,
  Axes -> False,
  Filling -> Bottom,
  FrameTicks -> {{Automatic, Automatic}, {{{2007, 1, 15}, Red}}, None},
  Frame -> False,
  GridLines -> {{datemarker}, None},
  Joined -> True,
  ImageSize -> 120,
  PlotRange -> All
  ]

insert {2005,1,1} as the marker date:

Grid[{{"Topic No.", "Sparkline"}, {"1", sparkline[data[[1]], {2005, 1, 1}]},
{"2", sparkline[data[[2]],{2005, 1, 1}]}},Frame -> All, Background -> {None, {LightGray}}]

enter image description here

You can insert a GridLinesStyle option to style the lines.

$\endgroup$
3
$\begingroup$

Method 1: Using Frame and FrameTicks:

ClearAll[sparkline2B];
sparkline2B[data_, datespec_, linedates_, linestyles_] := 
DateListPlot[data, datespec,
 Joined -> True,
 FrameTicks -> {Thread[{DateList /@ linedates, "", {.2, .0}, 
  linestyles}, List, {1, -1, 3}], Automatic, Automatic, Automatic},
 Frame -> {True, False, False, False}, FrameStyle -> White,
 Axes -> False, GridLines -> None, PlotRange -> All, 
 Filling -> Bottom, AspectRatio -> 0.2, ImageSize -> 420]

The third argument can be mixed list of elements with Heads: List, String, DateList, or DateString:

Examples:

sparkline2B[data, {1997}, {{2003, 3, 20}}, Directive[Thick, Red]]

enter image description here

sparkline2B[data, {1997}, {{2003, 3, 20}, "15 Jan, 2007"},Directive[Thick, Red]]

enter image description here

dates = {"15 Jan, 1999", {2000, 3, 20}, DateString["15 Jan, 2003"],
 DateString[{2004, 5}], DateList[{2006, 3, 20}], DateList["15 Jan, 2007"]};
colors = {Red, Directive[Thick, Green], Directive[Blue, Dashed],
 Directive[Brown, Dashed, Thick], Directive[Blue, Thin, Dotted], Purple};
sparkline2B[data, {1997}, dates2, colors2]

enter image description here

Method 2: Yet another alternative is to use a combination of options Axes, AxesOrigin, Ticks with appropriate settings:

 ClearAll[sparkline2];
 sparkline2[data_, date_] := 
 DateListPlot[data, {1997}, Joined -> True, Frame -> False, 
 PlotRange -> All, Filling -> Bottom, AspectRatio -> 0.2, ImageSize -> 120,   
 Axes -> {False, True}, 
 AxesOrigin -> {DateList[date], Automatic}, 
 AxesStyle -> Red, 
 Ticks -> {{}, {}}, 
 ]

Example:

 {#, sparkline2[data, #]} & /@ 
 {"15 Jan, 1999", {2000, 3, 20}, 
  DateString["15 Jan, 2003"], 
  DateString[{2004, 5}], 
  DateList[{2006, 3, 20}], 
  DateList["15 Jan, 2007"]} 
  //  Grid[#, Dividers -> All] &

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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