Jeroen
Jeroen

Reputation: 957

Matplotlib: Getting full hour ticks on y-axis in scatterplot

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

Scatter plot

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

Answers (3)

Boergler
Boergler

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

screenpaver
screenpaver

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()                                                                                                   

enter image description here

Upvotes: 1

Demetri Pananos
Demetri Pananos

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

Related Questions