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.

This text file logs the time that a process (identified by a number) changes state ("Brown", "Blue" etc.")

2014-08-29 03:59:52 , 27273 , Brown
2014-08-29 03:59:53 , 27276 , Green
2014-08-29 03:59:55 , 27276 , Brown
2014-08-29 03:59:57 , 27303 , Red
2014-08-29 03:59:58 , 27303 , Green
2014-08-29 03:59:59 , 27303 , Brown
2014-08-29 04:00:04 , 27317 , Brown
2014-08-29 04:00:07 , 27331 , Blue
2014-08-29 04:00:07 , 27334 , Blue
2014-08-29 04:00:08 , 27331 , Red
2014-08-29 04:00:08 , 27334 , Cyan

What I try to do is to plot horizontal bars as time intervals, colored according to the third column, where x-axis is time, y-axis is process id number. One of the colors (probably Cyan) should not be displayed, as it marks the interval end.

It is actually a timeline of many parallel events.

DatePlot does not seem to help. Any suggestions?

share|improve this question

3 Answers 3

dat = "2014-08-29 03:59:52 27273  Brown
       2014-08-29 03:59:53  27276  Green
       2014-08-29 03:59:55  27276  Brown
       2014-08-29 03:59:57  27303  Red
       2014-08-29 03:59:58  27303  Green
       2014-08-29 03:59:59  27303  Brown
       2014-08-29 04:00:04  27317  Brown
       2014-08-29 04:00:07  27331  Blue
       2014-08-29 04:00:07  27334  Blue
       2014-08-29 04:00:08  27331  Red
       2014-08-29 04:00:08  27334  Cyan";
 inputdata = ImportString[dat];

DateListPlot

ClearAll[dateListBars];
dateListBars[inpdata_, leftpadding_, rightpadding_, 
  opts : OptionsPattern[]] := 
 Module[{datasets, dates, firstdate, lastdate,
   labels, colors, gdt, dlPltF, options,
   data = {#3, DateList[#1 <> " " <> #2], ToExpression@#4} & @@@ 
     inpdata},
  gdt = GatherBy[data, First];
  {labels, colors} = Transpose[{#[[1, 1]], #[[All, 3]]} & /@ gdt];
  datasets = {#[[1, 1]], AbsoluteTime /@ #[[All, 2]], #[[All, 3]]} & /@
     gdt;
  dates = DeleteDuplicates@data[[All, 2]];
  {firstdate, lastdate} = DateList /@ ({leftpadding, rightpadding} +
      Through[{Min, Max}[AbsoluteTime /@ dates]]);
  dlPltF := DateListPlot[Thread[{{firstdate, lastdate}, #2[[1]]}],
     Joined -> True, Mesh -> {#[[2]]},
     MeshShading -> {White, Sequence @@ #[[3]], White},
     BaseStyle -> Directive[Thickness[.075], CapForm["Butt"]],
     Frame -> True, MeshStyle -> Opacity[0]] &;
  options = {PlotRange -> All, 
    GridLines -> {AbsoluteTime /@ dates, None},
    Method -> {"GridLinesInFront" -> True},
    FrameTicks -> {{Thread[{Range[Length@datasets], labels}], None},
      {{AbsoluteTime@#, Rotate[DateString[#,
            {"Hour", ":", "Minute", ":", "Second"}], Pi/2]} & /@
        {firstdate, Sequence @@ dates, lastdate}, None}},
    PlotRangePadding -> {{.5, .5}, {.5, .5}}};
  Show[MapIndexed[dlPltF, datasets], Sequence @@ options, opts]]


dateListBars[inputdata, -1, 5, ImageSize -> 600, LabelStyle -> 16] /. Cyan -> White

enter image description here

BarChart

Data preparation:

data = {#3, DateList[#1 <> " " <> #2], ToExpression@#4} & @@@ ImportString[dat];
{labels, colors} =  Transpose[{#[[1, 1]], #[[All, 3]]} & /@ GatherBy[data, First]];
datasets = {#[[1,1]], AbsoluteTime /@ #[[All, 2]], #[[All, 3]]} & /@ GatherBy[data, First];
dates = DeleteDuplicates@data[[All, 2]];
{leftpadding, rightpadding} = {-1, 5};
{firstdate, lastdate} = DateList /@ ({leftpadding, rightpadding} +
                                      Through[{Min, Max}[AbsoluteTime /@ dates]]);
bcheights = 
  DateDifference[DateList[#1], DateList[#2], "Second"][[1]] & @@@ 
     Partition[#, 2, 
      1] & /@ (Append[Prepend[#, AbsoluteTime[firstdate]], 
       AbsoluteTime[lastdate]] & /@ datasets[[All, 2]] );
bccolors = Prepend[#, White] & /@ colors;
bcdata = Thread[Style[#, #2]] & @@@ Transpose[{bcheights, bccolors}];

Handling date ticks:

bcticks = Union[Flatten[Accumulate@# & /@ bcheights]];
bcticks = Thread[{bcticks, Rotate[DateString[
        DatePlus[firstdate, {#, "Second"}],
        {"Hour", ":", "Minute", ":", "Second"}], Pi/2] & /@
     Union[Flatten[Accumulate@# & /@ bcheights]]}];

and the options

bcoptions = {ChartLayout -> "Stacked", BarOrigin -> Left,
   ChartLabels -> {Placed[labels, Axis], None},
   ChartBaseStyle -> Directive[Opacity[1], EdgeForm[]], 
   LabelStyle -> 16,
   Frame -> {{False, True}, {True, True}},
   FrameTicks -> {{None, None}, {bcticks, None}},
   GridLines -> {bcticks[[All, 1]], None}, 
   Method -> {"GridLinesInFront" -> True}, ImageSize -> 600};


 BarChart[bcdata, bcoptions] /. Cyan -> White

enter image description here

BulletGauge

bgaugedata = 
  Transpose[{Accumulate /@ bcheights, Prepend[#, White] & /@ colors, 
    labels}];
Panel[Column[
   Reverse[BulletGauge[0, foo, Append[Prepend[#1 + 5, 0], 25],
         ScaleRangeStyle -> Thread[{#2, White}], GaugeMarkers -> None,
         GaugeLabels -> 
          Placed[Style[#3, "Subsubsection"], {2, Bottom}],
         ImageSize -> 600, Axes -> False, Frame -> False, 
         TicksStyle -> Opacity[0], ReferenceMarkerStyle -> Opacity[0],
         AspectRatio -> 1/10] & @@ # & /@ bgaugedata], 
   Spacings -> -2]] /. Cyan -> White

enter image description here

TODO: Date ticks ...

share|improve this answer
    
wow...this beautiful+1 –  ubpdqn Sep 2 at 8:32
    
thank you @ubpdqn.. –  kguler Sep 2 at 8:45
    
Thanks, these are great. –  user32916 Sep 2 at 11:14
dat = "2014-08-29 03:59:52 27273  Brown
  2014-08-29 03:59:53  27276  Green
  2014-08-29 03:59:55  27276  Brown
  2014-08-29 03:59:57  27303  Red
  2014-08-29 03:59:58  27303  Green
  2014-08-29 03:59:59  27303  Brown
  2014-08-29 04:00:04  27317  Brown
  2014-08-29 04:00:07  27331  Blue
  2014-08-29 04:00:07  27334  Blue
  2014-08-29 04:00:08  27331  Red
  2014-08-29 04:00:08  27334  Cyan";
data = {DateList[#1 <> " " <> #2], #3, #4} & @@@ ImportString[dat];
{dates, val, col} = Transpose[data];
dlp = DateListPlot[MapThread[{{#1, #2}, {Last@dates, #2}} &, {Most@dates, Most@val}], 
     ImageSize -> 500, 
     PlotStyle -> (Thread[{Thickness[0.01],Most@(ToExpression /@ col)}]), PlotLegends ->    (Most@val), 
  FrameTicks -> {Automatic, None}]

enter image description here

Note if, as the question suggest, the "values" are labels and the bars are desired to be equally spaced this could be done using MapIndexed rather than MapThread

share|improve this answer
    
Oooh right. Now I see what the OP meant :) –  Öskå Sep 1 at 10:59
    
@Öskå happens to us all :) –  ubpdqn Sep 1 at 11:14
    
@Öskå in the OP's question he specifically notes the last entry is end of interval and Cyan will not be needed...hence Most and no Cyan. –  ubpdqn Sep 1 at 11:17
    
Thanks very much. I had to do some changes on the code, namely erased the "PlotLegends" and the "ImportString". –  user32916 Sep 2 at 11:13
    
@user32916 I had changed your original data (omitting commas). kguler has posted a much better answer than mine –  ubpdqn Sep 2 at 11:27

With se.dat being exactly what you provided:

dat = StringSplit[#, ","] & /@ Import["~/se.dat", "List"];
dates = ToExpression /@ 
          (StringSplit[#, ","] & /@ 
            (StringReplace[StringTrim@#, {"-" | " " | ":" -> ","}] & /@ First /@ dat))
val = ToExpression[#[[2]]] & /@ dat
col = ToExpression[#[[3]]] & /@ dat
DateListPlot[List /@ Thread@{dates, val}, PlotStyle -> col]

Mathematica graphics

share|improve this answer
    
Thanks everyone! –  user32916 Sep 2 at 11:14

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.