-1

I'd like to plot pandas DataFrame as a line chart with x-axis having '%H:%M' style.

However, when I try this:

import datetime
import pandas as pd
import numpy as np
d = pd.DataFrame([np.random.rand(3) for _ in range(9)])
d.index = [datetime.time(i, 0) for i in range(15,24)]
ax = d.plot(xticks=d.index)
plt.xticks([x.strftime("%H:%M") for x in d.index][0::4])

Chart with %H:%M:%s style x-axis is ploted:

enter image description here

Following this answer, I've added DateFormatter:

import matplotlib.dates as md
d = pd.DataFrame([np.random.rand(3) for _ in range(9)])
d.index = [datetime.time(i, 0) for i in range(15,24)]
ax = d.plot(xticks=d.index)
#plt.xticks([x.strftime("%H:%M") for x in d.index][0::4])
ax.xaxis.set_major_formatter(md.DateFormatter('%H:%M'))

Unfortunately, I got a plot with only 00:00 x-axis.

enter image description here

I'd like to get %H:%M style x-axis with proper interval ticks label like "15:00, 17:00, 19:00, 21:00" (every 2 intervals here). How do I realize that?

Community
  • 1
  • 1
Light Yagmi
  • 5,085
  • 12
  • 43
  • 64

1 Answers1

0

I believe that is happening because DateFormatting is not recognizing the instructions for "%H:%M". Just replace those by the integer instruction, %d, and it should give you the result you want (or at least something you can adapt). In the following fix of your code I also added rotation to labels to avoid excessive cluttering in the x-axis:

import datetime
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as md
d = pd.DataFrame([np.random.rand(3) for _ in range(9)])
d.index = [datetime.time(i, 0) for i in range(15,24)]
ax = d.plot(xticks=d.index)
plt.xticks(rotation=45)  # Changed here
ax.xaxis.set_major_formatter(md.DateFormatter('%d:%d')) # and here...
plt.show()

EDIT: The example above only changes the interpreter string for the formatter. I didn't mess with the data or anything else. In any case ideally you should be using this:

ax.xaxis.set_major_locator(md.HourLocator(byhour=range(0,24,2)))

, to achieve what you want. But I just tested it and it appears to have a bug. That being said my advice is that you parse directly your desired labels into the xticks.

import datetime
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
d = pd.DataFrame([np.random.rand(3) for _ in range(9)])
d.index = [datetime.time(i, 0).hour for i in range(15,24)]
ax = d.plot(xticks=d.index)
plt.xticks([datetime.time(i, 0).hour for i in range(15,24)][0::2],["%d:00"%datetime.time(i, 0).hour for i in range(15,24)][0::2],rotation=45)  # Changed here
plt.show()

, which results in this:

x label with hours with a step of 2

armatita
  • 12,825
  • 8
  • 48
  • 49
  • I just changed what I felt was your most urgent problem: the fact that your labels were zeroed no matter the location (the rest I assumed you would adapt). Down voting an answer just because it does not give a copy paste solution seems like a new trend in SO. Personally I find it regrettable but I guess that's how it is. I've edited the post with a possible solution to your problem. – armatita Mar 24 '16 at 12:15