Reputation: 957
I'm plotting some measured speeds from cars in a scatterplot. I'd like to show that low speeds often occur during certain periods of the day. Plotting works fine, but I'm not happy about the y-axis.
import pandas as pd
import matplotlib.pyplot as plt
Time = ['2018-03-16 16:15', '2018-03-16 16:30', '2018-03-16 16:45']
Speed = [56, 46, 51]
df = pd.DataFrame({'Time':pd.to_datetime(Time), 'Speed':Speed})
df.set_index('Time', inplace=True)
plt.scatter(df.index, df.index.time)
plt.xlim('2018-03-04','2018-03-31')
plt.ylim('06:00','20:00')
plt.show()
Gives
I would like the y-axis to include only full hours (maybe 06:00, 12:00, 16:00 and 20:00)
I tried stuff like
fig,ax = plt.subplots()
hours =mdates.HourLocator(interval=1)
h_fmt =mdates.DateFormatter('%H')
ax.scatter(df.index, df.index.time)
ax.yaxis.set_major_locator(hours)
ax.yaxis.set_major_formatter(h_fmt)
fig.autofmt_xdate()
plt.show()
Which seems to be generating loads of ticks.
Does anybody have a solution for this?
Upvotes: 0
Views: 467
Reputation: 301
It's something to do with how matplotlib handles datetime.time objects. Try this:
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
Time = ['2018-03-16 16:15', '2018-03-16 16:30', '2018-03-16 16:45']
time = [datetime.strptime(d,'%Y-%m-%d %H:%M') for d in Time]
Speed = [56, 46, 51]
df = pd.DataFrame({'Time':pd.to_datetime(Time), 'Speed':Speed})
df.set_index('Time', inplace=True)
plt.scatter(df.index, time)
plt.xlim('2018-03-04','2018-03-31')
plt.ylim('2018-03-16 06:00','2018-03-16 20:00')
plt.show()
Upvotes: 1
Reputation: 1130
Something like this?
plt.scatter(df.index, df.index.time)
plt.gcf().autofmt_xdate()
yticks = [datetime.time(6,0),datetime.time(10,0),datetime.time(14,0),datetime.time(18,0),datetime.time(22,0)]
ax = plt.gca()
ax.set_yticks(yticks)
plt.show()
Upvotes: 1
Reputation: 7404
This isn't an ideal solution, but you could just do something like
df['time'] = df.index.hour + df.index.minute/60 #if Python 2.x Cast minute as a float
df.plot(x = 'time',y = 'Speed', kind = 'scatter')
You will have to interpret the minutes as fractions of an hour (e.g. 16.5 is really 4:30 PM) but it is good enough to do what you want.
Upvotes: 0