4

I have the type of following data:

Begin   End                        Event
 2003  2007                      Event 1
 1991  2016                      Event 2
 2008  2016                      Event 3
 1986  2015                      Event 4
 2013  2013                      Event 5
 1994  1999                      Event 6
 2002  2002                      Event 7

My goal is to make a timeline of these events, ie to draw a series of distinct straight and horizontal bars from date 1 to date 2 with the names of the events on them.

I am currently trying my luck with the barh function from matplotlib, but I wonder if there is already a ready-made module in python that would integrate nicely with matplotlib and pandas to do so ?

baloo
  • 397
  • 3
  • 12

2 Answers2

13

I don't think there is the need to for a special function here. Using plt.barh is directly giving you the desired plot.

import matplotlib.pyplot as plt
import numpy as np

begin = np.array([2003,1991,2008,1986,2013,1994,2002])
end =   np.array([2007,2016,2016,2015,2013,1999,2002])
event = ["Event {}".format(i) for i in range(len(begin))]

plt.barh(range(len(begin)),  end-begin, left=begin)

plt.yticks(range(len(begin)), event)
plt.show()

enter image description here

Note that Event 4 and 6 seem missing, because start and end are identical. If you want to interprete end as being the end of the year, you may add 1 to it,

plt.barh(range(len(begin)),  end-begin+1, left=begin)

enter image description here

ImportanceOfBeingErnest
  • 289,005
  • 45
  • 571
  • 615
  • It could be easier to parameter if there was a macro, but thanks for the tip. – baloo Jun 13 '17 at 12:31
  • A macro which replaces two lines of code by one single line? – ImportanceOfBeingErnest Jun 13 '17 at 12:35
  • And also adds pre-set parameters so that the code is more readable and quicker to write or understand. That's why I prefer pandas over numpy + matplotlib as much as possible. – baloo Jun 15 '17 at 22:21
  • The code above is one single command, which takes a lot of parameters, if needed. I don't quite understand what you want more than that. But if you want to write a function which uses some default parameters, just write that function. If you have a problem doing so, ask a question about it. – ImportanceOfBeingErnest Jun 15 '17 at 22:34
  • Note that if the first parameter of barh (height) is a function F(begin, end, event) applied to the corresponding triplet, then the events can be grouped allowing to have more than one event in a single row, (like https://mathigon.org/timeline.). Of course the function should group only non overlapping events in order to them be rendered properly – nadapez Dec 07 '21 at 12:58
  • Also it would be nice to have a label inside the bars themself – nadapez Dec 07 '21 at 13:01
0

Made a different serialsation of input data as below, a bit more natural for the incoming data:

events = [('Event 0', 2003, 2007),
     ('Event 1', 1991, 2016),
     ('Event 2', 2008, 2016)
     #...
     ]

Also wrapped in a function, as question author may have wanted.

See at https://github.com/epogrebnyak/hrange/blob/master/hrange.py

Evgeny
  • 3,807
  • 2
  • 17
  • 35