2

I'm trying to visually represent the status of devices (being either offline or online) as a timeline. My data (for one device) looks like this, where True represents online and False represents offline:

Time
2019-09-01 14:38:38     True
2019-09-01 14:39:08     True
2019-09-01 14:39:38     True
2019-09-01 14:40:08     True
2019-09-01 14:40:38     True

2019-10-04 17:35:55     True
2019-10-04 17:36:25    False
2019-10-04 17:36:55    False
2019-10-04 17:37:25    False
2019-10-04 17:37:55     True
Name: Time, Length: 95368, dtype: bool

I would like to represent this as a horizontal barchart where datetime is on the x-axis and each device has its own bar with green representing online and red for offline.

What I'm trying to do is similar to what was asked here. I copied that code and adapted it slightly:

# plot green for event==1
s1 = data[data == 1].astype(int)
inxval = matplotlib.dates.date2num(s1.index.to_pydatetime())
times= list(zip(inxval, np.ones(len(s1))))
plt.broken_barh(times, (-1,1), color="green")

# plot red for event==0
s2 = data[data == 0].astype(int)
inxval = matplotlib.dates.date2num(s2.index.to_pydatetime())
times= list(zip(inxval, np.ones(len(s2))))
plt.broken_barh(times, (-1,1), color="red")

#format axes
ax.margins(0)
ax.set_yticks([])
ax.xaxis.set_major_locator(matplotlib.dates.MonthLocator())
ax.xaxis.set_minor_locator(matplotlib.dates.DayLocator())
monthFmt = matplotlib.dates.DateFormatter("%b")
ax.xaxis.set_major_formatter(monthFmt)
plt.tight_layout()
plt.show()

Unfortunately this takes forever to load (my dataset is quite large) and I'd like to directly have the timestamps as the x-axis, so without using date2num. Is there a more elegant way of doing this?

Thanks!

TMD
  • 21
  • 1
  • The code seems correct. One cannot find out what "forever to load" means and what you would like to be more elegantly. – ImportanceOfBeingErnest Oct 10 '19 at 11:12
  • @ImportanceOfBeingErnest Yes, the code is correct in the sense that it works. However, it takes about 15 seconds to load with 95k datapoints whereas a simple line chart of the same data loads almost instantly. Additionally, I'd like to have nicer x-labels that are generated automatically based on the timestamps, just like plt.plot(data). The linked question is from 2017 so perhaps there are more efficient ways of solving this problem now. – TMD Oct 10 '19 at 11:22
  • 15 seconds is not too surprising for 100k of datapoints. Mind that bars are different from lines. But of course you could create a `LineCollection` instead, to make it faster. The labels are the result of a locator/formatter. You can hence use the same locator/formatter you get with `plt.plot`. – ImportanceOfBeingErnest Oct 10 '19 at 11:36
  • @ImportanceOfBeingErnest Okay, and how would one go about creating a line collection and using the same locator/formatter as plt.plot? – TMD Oct 10 '19 at 12:16

0 Answers0