0

I have two Pandas series with time axis. The data is presented (roughly, not exactly) every 5 minutes and spans 2 days. There are no actual missing values, but two unevenly spaced data series that do not necessarily have data at the same instants. I want to plot these two series with bars, one on top of the other. I use the code below to create a Dataframe and then call its plot.bar() method:

df = pd.concat({"download": series_ok, "failed": series_fail}, axis=1)
axes = df.plot.bar(rot=0, subplots=True, color={"failed": "red", "download": "green"})

This almost works, but the problem is that the spacing of xtics is so small that the whole plot takes several seconds to work, the time information is unreadable and it's so heavy that it's effectively non interactive.

How can I tweak the xtics to indicate that I want a separation of, say, 1 or even 2 hours.

enter image description here

Pythonist
  • 1,937
  • 1
  • 14
  • 25

1 Answers1

0

Alright so here is what I came up with:

Create a dummy dataframe (sampled every 5 minutes):

import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import matplotlib.dates as mdates

df = pd.DataFrame(np.random.rand(581,2),index=pd.date_range(start='2020-01-01 00:00:00', end='2020-01-03 00:24:00', freq='5T'))
print(df)

Pandas will automatically perform a tick resolution change assuming regular fequency timeseries data. The x_compact parameter = True will suppress that behavior.

ax = df.plot(x_compat=True)
ax.xaxis.set_major_locator(mdates.HourLocator(interval=4))   #to get a tick every 4 hours
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) #format what the labels look like

Edit: I noticed the labels and x ticks were not quite in alignment, this should hopefully fix that:

for label in ax.xaxis.get_ticklabels():
    label.set_horizontalalignment('center')
ax.xaxis.set_tick_params(rotation=90)  # rotate the x axis labels, if you want
plt.show()

enter image description here

I don't know what exactly your data looks like so hopefully this is enough to go on.

Edit

Alright so after realizing you code uses bar plots I have updated the code. I think you are going to have to use matplotlib in order to plot the bar plots and get the datetime to show up properly and edit the x axis (see this question and this question).

So try to adapt your code to do something similar to as follows:

import random
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import matplotlib.dates as mdates
random.seed(30)

df = pd.DataFrame({
    "Site 1": np.random.rand(577),
    "Site 2": np.random.rand(577),})

idx = pd.date_range(start='2020-01-01 00:00:00', end='2020-01-03 00:00:00',freq ='5T')
df = df.set_index(idx)

fig, ax = plt.subplots(figsize=(12,8))
ax.bar(df.index, df['Site 1'], width=0.005)
ax.xaxis.set_major_locator(mdates.HourLocator(interval=4))   #to get a tick every 4 hours
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
ax.tick_params(axis='x', labelrotation = 90) 
plt.show()

You will need to set up a subplot here to show both of the plots but this should hopefully get you on the right track. Sorry about the confusion, I am learning these things right there with you!

Jeff Coldplume
  • 343
  • 1
  • 13
  • Thanks. The `x_compact` (which I cannot find it documented) does fix the problem for plots using likes. Unfortunately it does not work with `kind='bar'`, which is the scenario I have. It raises the exception: `AttributeError: 'Rectangle' object has no property 'x_compat'` – Pythonist May 27 '21 at 11:27
  • 1
    Ah yes, my mistake I thought your image was showing line plots. I might be able to take a look in a bit. What happens if you just remove the x_compat=True portion and then run it? – Jeff Coldplume May 27 '21 at 18:56
  • Then I get the figure that opened the question, with thousands of tics and labels. – Pythonist May 27 '21 at 19:27
  • I think you are going to have to plot using matplotlib and not pandas; see the following question: https://stackoverflow.com/questions/42455391/python-different-behaviour-of-datetimeindex-while-plotting-line-and-bar-plots – Jeff Coldplume May 27 '21 at 19:39
  • I have updated my answer, hopefully that resolved it. You may have to adjust the widths of the bars since there is so much data you are squeezing into one plot, but I think it should still work alright. Here is another link that shows an example of the bar plot with the datetime: https://scentellegher.github.io/programming/2017/05/24/pandas-bar-plot-with-formatted-dates.html – Jeff Coldplume May 27 '21 at 19:52
  • It works nicely after working around Pandas and going straight to Matplotlib. Thanks! – Pythonist May 28 '21 at 07:47