2
$\begingroup$

I found this question where someone put some code to graphic a timeline based on a certain number of events. In that code in particular, the events are hard coded one by one, I want to modify it, so it can get the events from an array. This is the link to that question:

how to make graphic timelines in mathematica

What I have is an array of events, like so:

{{0,arrival ,1,1},{0.35749,departure ,1},{6,arrival ,2,3}}

Where the first position is the time of the event, the second position stores the type of the event (arrival or departure) and the other fields are not necessary in the graphic.

I'll post the code from the link so it is easier for you to look at it, as I said, it creates the graphic, but the events don't come from an array. This block of code creates the event frames:

EventFrame[str_, {date_, height_}, OptionsPattern[FontSize -> 14]] := 
Graphics[{
  Black, Thick, Line[{{date, height}, {date, 0}}], 
  Text[Framed[Style[str, FontSize -> OptionValue[FontSize]],
  {Background -> White, FrameStyle -> Black,FrameMargins -> Automatic}],       
  {date, height}]
}]

This creates the graphic for the timeline:

TimeLine[min_, max_] := 
Graphics[{ 
  (* TimeLine *)
  Black, Thick, Line[{{min, 0}, {max, 0}}], 
  (* year ticks *)
  Thin, Table[Line[{{x, 0.5}, {x, 0}}], {x, min, max}],
  (* year labels *)
  Table[Text[Framed[Style[x, FontSize -> 20],
  {Background -> White, FrameStyle -> White}], {x, 1}], {x, min, max}]
}]

And this wraps all of the above, here is where the events are hardcoded

Pane[Show[
  EventFrame["Event 1", {DateConv[1988, 6, 2], 4}],
  EventFrame["Event 2", {DateConv[1990, 8, 15], -2}],
  (************************)
  TimeLine[1985, 1995],
  (************************)
  AspectRatio -> 1/6, ImageSize -> {1400, 280}],
  (************************)
  ImageSize -> {550, 280}, Scrollbars -> {True, False}]

I won't use the function that converts the date because my events are based on seconds, not by dates.

I tried using a for loop within the last block of code, instead of creating the events individually, but it doesn't give the Show function a proper argument, like this:

For[i = 1, i < Length[events],
EventFrame[events[[i]][[2]],{events[[i]][[1]], -1}]
, i++]

What would be the best approach to accomplish this? Thanks!

$\endgroup$
2
$\begingroup$

I wrote the original timeline answer.

Your code does not work because in Mathematica For function does not produce output. Show function expects Graphics[] or List[Graphics[]] as input.

I assume arrival and departure are strings

events = {{0, "arrival", 1, 1}, {0.35749, "departure", 1}, {6, "arrival", 2,3}};

Table is a function that can loop through list and has list as output.

Table[
EventFrame[x[[2]], {x[[1]], -1}],
     {x, events}]

Inside Show :

Show[
 Table[
 EventFrame[x[[2]], {x[[1]], -1}],
 {x, events}],
 (************************)
 TimeLine[0, 10],
 (************************)
 AspectRatio -> 1/3]

But there is a problem: since height is hard-coded as -1, some of the labels will be hard to see. We will need a function that generates EventFrames with different heights.

Pane[Show[
Table[
EventFrame[events[[x]][[2]], {events[[x]][[1]], -(Mod[x, 2] + 1)}],
{x, 1, Length@events}],
(************************)
TimeLine[0, 10],
(************************)
AspectRatio -> 1/6, ImageSize -> {1400/2, 280}],
(************************)
ImageSize -> {550, 280}, Scrollbars -> {True, False}]

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.