Reputation: 169
My seaborn/matplotib plot is not recognizing time as time.
temp t d
0 39.9 00:24:23 03-21-2021
1 39.9 00:28:32 03-21-2021
2 39.4 00:32:41 03-21-2021
3 39.2 00:36:48 03-21-2021
4 38.8 00:40:57 03-21-2021
.. ... ... ...
240 59.0 17:02:14 03-21-2021
241 58.5 17:06:23 03-21-2021
242 58.5 17:10:31 03-21-2021
243 58.5 17:14:40 03-21-2021
244 58.1 17:18:49 03-21-2021
I'm trying to maker my x-ticks round-up to the hour
my research has led me to believe my time data is not formatted as a in a way that matplotlib recognizes as time.
this is the area of my code that generates the plot:
#panda datafram is 'values'
g=sns.lineplot(x='t', y='temp', data=values,color="darkblue")
plt.ylim(values['temp'].min()-1, values['temp'].max()+1)
plt.xticks(rotation=90)
# compensate for axis labels getting clipped off
plt.subplots_adjust(bottom=0.15, left=0.15)
g.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
g.xaxis.set_major_locator(mdates.HourLocator(interval = 400))
g.set(xlabel='Time', ylabel='Temperature')
#create unique filename based on time
filename= "Graph-" +str(dt.datetime.now().hour)+"-"+str(dt.datetime.now().minute)+".png"
plt.savefig(filename)
If its not clear look at my X axis in my plot, the hours are all messed up ( 17, 9, 1) if you look at my data frame the time data is obvious.
I can either save my time data in a different format or I need to reformat my time data for seaborn/matplotlib ????
Upvotes: 0
Views: 588
Reputation: 41327
Since values.t
is currently type object
, convert it to_datetime()
before calling sns.lineplot()
:
values.t = pd.to_datetime(values.t)
g = sns.lineplot(x='t', y='temp', data=values, color='darkblue')
(You can verify the conversion by checking whether values.t.dtype
is some kind of datetime
instead of object
.)
Upvotes: 1
Reputation: 5479
Here is another way to do it. Combine your date and time columns and convert them to a column of datetime objects, then use matplotlib.dates.date2num() to convert the datetimes to numerical value than you can use for the x axis:
from matplotlib import pyplot as plt
import pandas as pd
from matplotlib import dates as mdates
import datetime
df = pd.read_csv('sample.csv')
df['dt_string'] = df.d + ' ' + df.t
df['dt'] = df['dt_string'].apply(lambda x: datetime.datetime.strptime(x, "%m-%d-%Y %H:%M:%S"))
df['time_num'] = mdates.date2num(df.dt)
print(df)
#the first 5 rows of your dataframe:
temp t ... dt time_num
0 39.9 00:24:23 ... 2021-03-21 00:24:23 18707.016933
1 39.9 00:28:32 ... 2021-03-21 00:28:32 18707.019815
2 39.4 00:32:41 ... 2021-03-21 00:32:41 18707.022697
3 39.2 00:36:48 ... 2021-03-21 00:36:48 18707.025556
4 38.8 00:40:57 ... 2021-03-21 00:40:57 18707.028438
Then plot as follows:
fig, ax = plt.subplots()
ax.plot(df.time_num, df.temp)
ax.set_xticks(df.dt)
ax.set_xticklabels(df.dt)
ax.set_xlabel('DateTime')
ax.set_ylabel('Time')
fig.autofmt_xdate()
plt.show()
Upvotes: 0
Reputation: 8593
You can pass the name of the column containing you string-formatted timestamps to the parse_dates
argument when reading your csv file. The important line would therefore be:
df = pd.read_csv(data, sep='\s+', parse_dates=['t'])
I used your data snippet to create some sample data spanning some hours and built some code based on this SO answer.
My code snippet looks like this:
import io
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
data_string = """
temp t d
39.9 00:24:23 03-21-2021
39.9 00:28:32 03-21-2021
39.4 00:32:41 03-21-2021
39.2 00:36:48 03-21-2021
38.8 00:40:57 03-21-2021
39.9 00:50:23 03-21-2021
39.9 01:28:32 03-21-2021
39.4 01:32:41 03-21-2021
39.2 01:36:48 03-21-2021
38.8 01:40:57 03-21-2021
39.9 01:50:23 03-21-2021
39.9 02:24:23 03-21-2021
39.9 02:28:32 03-21-2021
39.4 02:32:41 03-21-2021
39.2 02:36:48 03-21-2021
38.8 02:40:57 03-21-2021
39.9 02:50:23 03-21-2021
39.9 03:28:32 03-21-2021
39.4 03:32:41 03-21-2021
39.2 03:36:48 03-21-2021
38.8 03:40:57 03-21-2021
39.9 03:50:23 03-21-2021
39.9 04:24:23 03-21-2021
39.9 04:28:32 03-21-2021
39.4 04:32:41 03-21-2021
39.2 04:36:48 03-21-2021
38.8 04:40:57 03-21-2021
39.9 04:50:23 03-21-2021
39.9 05:28:32 03-21-2021
39.4 05:32:41 03-21-2021
39.2 05:36:48 03-21-2021
38.8 05:40:57 03-21-2021
39.9 05:50:23 03-21-2021
"""
data = io.StringIO(data_string)
df = pd.read_csv(data, sep='\s+', parse_dates=['t'])
print(df)
hours = mdates.HourLocator(interval=1)
h_fmt = mdates.DateFormatter('%H:%M:%S')
fig, ax = plt.subplots()
ax.plot(df['t'], df['temp'])
ax.xaxis.set_major_locator(hours)
ax.xaxis.set_major_formatter(h_fmt)
fig.autofmt_xdate()
plt.show()
The following plot will be generated:
Upvotes: 0