3
$\begingroup$

I'm not sure how to add time format to bar plots. I'd like to be able to make one bar plot for one data set and another for another data set and then combine them, but I don't know how to offset each bar from the origin so they can overlap at the right times.

See image for an idea:

concept

$\endgroup$
  • 2
    $\begingroup$ Can you provide a small (but working) code sample of what you have so far? $\endgroup$ – ssch Oct 20 '13 at 16:33
  • $\begingroup$ How many bars do you want to display at one time? $\endgroup$ – DavidC Oct 20 '13 at 16:42
  • $\begingroup$ You may want to consider Gantt charts as a more general approach: demonstrations.wolfram.com/GanttChartsAndNetworkDiagrams $\endgroup$ – DavidC Oct 20 '13 at 19:07
13
$\begingroup$

For those with v. 10, here's one way. I didn't overlap the bars because it looks nicer this way, imho.

schedule[{t1_, t2_}, {t3_, t4_}] :=
 Module[{convert, ts = Flatten[{{t1, t2}, {t3, t4}}, 1][[All, 1]], hours},
  convert[{h_, min_}] := h + min/60;
  hours = Range[Min[ts] - 1, Max[ts] + 1];
  NumberLinePlot[{
    convert[t1] < x < convert[t2],
    convert[t3] < x < convert[t4]}, x, PlotTheme -> "Business",
   Ticks -> { hours /. {n_Integer :> {n, ToString[n] <> ":00"}}, None},
   Prolog -> {
     Text[TimeObject[t1], {convert[t1], 1}, {1, 0}],
     Text[TimeObject@t2, {convert[t2], 1}, {-1, 0}],
     Text[TimeObject@t3, {convert[t3], 2}, {1, 0}],
     Text[TimeObject@t4, {convert[t4], 2}, {-1, 0}]},
   GridLines -> {hours, {}},
   GridLinesStyle -> Directive[Orange, Dashed],
   ImageSize -> 500,
   BaseStyle -> 12,
   AspectRatio -> .3,
   PlotRangePadding -> {{2.5, 1.5}, Automatic},
   PlotStyle -> {Directive[Thickness[.06], Red, PointSize[Medium]], 
     Directive[Thickness[.06], Blue, PointSize[Medium]]}]]

 schedule[{{5, 20}, {7, 20}}, {{6, 1}, {8, 7}}]

schedule

If you prefer to display times without the TimeObject wrapper, simply replace each instance ofTimeObject[], with`.


These approaches should work on v.9. It overlaps the bars, as requested.

Assuming two time intervals,

t1 = "5:20"; t2 = "7:20";
t3 = "6:01"; t4 = "8:07";

toMin[t_] := ToExpression /@ StringSplit[t, ":"] /. {h_, m_} :> 60 h + m

Graphics[{  {Opacity[.4], EdgeForm[Black],
  Gray, Rectangle[{toMin@t1, 0}, {toMin@t2, 1}],
  Red, Rectangle[{toMin@t3, .5}, {toMin@t4, 1.5}]},
  Text[t1, Offset[{0, -20}, {toMin@t1, 0}]],
  Text[t2, Offset[{0, -20}, {toMin@t2, 0}]],
  Text[t3, Offset[{0, 50}, {toMin@t3, 0}]],
  Text[t4, Offset[{0, 50}, {toMin@t4, 0}]]},
  BaseStyle -> 20,
  AspectRatio -> 1/12]

times


Alternative Format

This approach can accommodate a larger number of time intervals. It should be easy to generalize the v.10 code to work in a similar fashion.

t1 = "5:20"; t2 = "7:20";
t3 = "6:01"; t4 = "8:07";
t5 = "1:23"; t6 = "4:19";
t7 = "3:14"; t8 = "4:51";

toMin[t_] := ToExpression /@ StringSplit[t, ":"] /. {h_, m_} :> 60 h + m;
seg[start_, end_, color_, ht_] := {EdgeForm[{Thickness[.003], color}], 
  Rectangle[{toMin@start, ht}, {toMin@end, ht + 1}],
  Black, 
  Text[start <> " \[RightArrow] ", {toMin@start, ht + .5}, {1, 0}], 
  Text[" \[LeftArrow] " <> end, {toMin@end, ht + .5}, {-1, 0}]};

 Graphics[{
  {White,
  seg @@@ {{t1, t2, Gray, 0}, {t3, t4, Red, 2}, {t5, t6, Blue, 4}, 
  {t7, t8,  Darker@Green, 6}}}},
  GridLines -> {toMin /@ {t1, t2, t3, t4, t5, t6, t7, t8}, {}},
  FrameTicks -> {Table[{60 k, k} /. {_Rational -> "", 0 -> 12}, {k, 0, 9, 1/4}], {}},
  FrameLabel -> {"PM"},
  ImageSize -> 600,
  PlotRange -> {{0, 540}, Automatic},
  PlotRangePadding -> 3,
  Frame -> {True, False},
  BaseStyle -> 16,
  AspectRatio -> 1/6]

schedule

$\endgroup$
2
$\begingroup$

The following should be enough to get you started:

f[min_, max_, pos_] := 
 Sequence[Rectangle[{min, pos}, {max, pos - 0.5}], {Opacity[1], 
   Text[Style[min, Large, Bold], {min, pos}], 
   Text[Style[max, Large, Bold], {max, pos}]}]
Graphics[{Opacity[0.5], Red, f[1, 2, 0], Blue, f[1.5, 3, .1]}]

enter image description here

You still need to write a function that transforms your times into horizontal coordinates …

$\endgroup$
  • $\begingroup$ Your code appears to have an error in it: $Failed $\endgroup$ – DavidC Oct 20 '13 at 19:17
1
$\begingroup$

In versions 10.1+ you can use TimelinePlot:

t1 = "5:20"; t2 = "7:20";
t3 = "6:01"; t4 = "8:07";
data = {{Interval[{t1, t2}]}, {Interval[{t3, t4}]}};

TimelinePlot[data, Spacings -> {5,1} ]

enter image description here

TimelinePlot[data, Spacings ->None,
 PlotStyle -> {Directive[Opacity[.5,Yellow], AbsoluteThickness[10],   CapForm["Round"]], 
   Directive[Opacity[.5,Blue], AbsoluteThickness[20], CapForm["Round"]]}]

enter image description here

$\endgroup$

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.