问题
I have this data:
Time = ['2017-03-13 00:01:00', '2017-03-13 00:02:00', '2017-03-13 23:59:00']
Speed = [20, 40.5, 100]
Kilometer = [1.4, 2.0, 4.1]
N130317 = pd.DataFrame({'Time':Time, 'Speed':Speed, 'Kilometer':Kilometer})
I have converted the time using:
N130317['Time'] = pd.to_datetime(N130317['Time'], format = '%Y-%m-%d %H:%M:%S')
N130317['Time'] = pd.to_datetime(N130317['Time'], format).apply(lambda x: x.time())
N130317['Time'] = N130317['Time'].map(lambda t: t.strftime('%H:%M'))
I have made a plot using:
marker_size=1 #sets size of dots
cm = plt.cm.get_cmap('plasma_r') #sets colour scheme
plt.scatter(N130317['Kilometer'], N130317['Time'], marker_size, c=N130317['Speed'], cmap=cm)
plt.title("NDW 13-03-17")
plt.xlabel("Kilometer")
plt.ylabel("Time")
plt.colorbar().set_label("Speed", labelpad=+1) #Makes a legend
plt.show()
But the graph shows up like this (all the time stamps show up on the y axis which evidently doesn't have the space for them - there is a time stamp for every minute in my date):
What can I do to solve this? Any help would be greatly appreciated. I have tried so many things online.
回答1:
I used these lines to create some data, replace them with your data:
from itertools import product
Time = [f'2017-03-13 {H}:{M}:{S}' for H, M, S in list(product([('0' + str(x))[-2:] for x in range(0, 24)],
[('0' + str(x))[-2:] for x in range(0, 60)],
[('0' + str(x))[-2:] for x in range(0, 60)]))]
Speed = list(130*np.random.rand(len(Time)))
Kilometer = list(50*np.random.rand(len(Time)))
N130317 = pd.DataFrame({'Time':Time, 'Speed':Speed, 'Kilometer':Kilometer})
I converted the N130317['Time']
to timestamp with this line:
N130317['Time'] = pd.to_datetime(N130317['Time'], format = '%Y-%m-%d %H:%M:%S')
Then I set the yaxis format property to date:
import matplotlib.dates as md
ax=plt.gca()
xfmt = md.DateFormatter('%H:%M')
ax.yaxis.set_major_formatter(xfmt)
The whole code is:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as md
from itertools import product
Time = [f'2017-03-13 {H}:{M}:{S}' for H, M, S in list(product([('0' + str(x))[-2:] for x in range(0, 24)],
[('0' + str(x))[-2:] for x in range(0, 60)],
[('0' + str(x))[-2:] for x in range(0, 60)]))]
Speed = list(130*np.random.rand(len(Time)))
Kilometer = list(50*np.random.rand(len(Time)))
N130317 = pd.DataFrame({'Time':Time, 'Speed':Speed, 'Kilometer':Kilometer})
N130317['Time'] = pd.to_datetime(N130317['Time'], format = '%Y-%m-%d %H:%M:%S')
marker_size = 1 # sets size of dots
cm = plt.cm.get_cmap('plasma_r') #sets colour scheme
plt.scatter(N130317['Kilometer'], N130317['Time'], marker_size, c=N130317['Speed'], cmap=cm)
ax=plt.gca()
xfmt = md.DateFormatter('%H:%M')
ax.yaxis.set_major_formatter(xfmt)
plt.title("NDW 13-03-17")
plt.xlabel("Kilometer")
plt.ylabel("Time")
plt.colorbar().set_label("Speed", labelpad=+1) #Makes a legend
plt.show()
and it gives me this plot:
Please, note that the pd.to_datetime()
has to be applied to a datetime
object, not to a string. If you run this code:
hour = '2017-03-13 00:00:00'
pd.to_datetime(hour, format = '%H:%M')
You will get this error message:
ValueError: time data '2017-03-13 00:00:00' does not match format '%H:%M' (match)
So you need to use this code, in order to convert the string to a datetime
:
hour = '2017-03-13 00:00:00'
hour = datetime.strptime(hour, '%Y-%m-%d %H:%M:%S')
pd.to_datetime(hour, format = '%H:%M')
This depends on the data type you have, I did not encounter this issue since I re-created the data as wrote above.
Version info
Python 3.7.0
matplotlib 3.2.1
numpy 1.18.4
pandas 1.0.4
来源:https://stackoverflow.com/questions/62289031/matplotlib-automatically-displaying-time-column-as-2-hour-ticks-on-y-axis-in-sc