xpress_embedo
xpress_embedo

Reputation: 377

Not able to display time on X-Axis using Matplotlib

I am reading some data from the file, and then I have to plot this data for visual representation. The data in the file is present in the following format:

16:08:45,64,31.2
16:08:46,60,29.3
16:08:47,60,29.3
16:08:48,60,29.3
16:08:49,60,29.3
.
.

This data is present in a file with the current date. The file consist of time (Hour:Minute:Second), Adc Counts, Temperature Value

I used the following code to read the data from the file using Pandas.

from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

year = 2018     # For 2018
'''
month = input ('Enter Month : ')
date = input ('Enter Date : ')
month = int(month)
date = int(date)
'''
# Hardcoded Values for Testing Purpose
month = 1
date = 20

headers = ['Time', 'ADC', 'Temperature']
filename = '%.2d-%.2d-%.2d.txt' % (month, date, year-2000)
print (filename)

try:
    df = pd.read_table( filename, ',', names=headers,\
                        engine='python', header=None)
except:
    print ('No Such File in Database')
    print ('Exiting Program')
    exit()

FMT = '%H:%M:%S'
df['Time'] = df['Time'].map(lambda x: datetime.strptime(str(x), FMT))
df['Time'] = df['Time'].map(lambda x: x.replace(day=date, month=month, year=year))

plt.plot( df['Time'], df['ADC'])

plt.ylim( [0,200])
#plt.gcf().autofmt_xdate()
plt.show()

Graph Generated

I didn't get why the x-axis doesn't have correct values. Is it due to the reason, that samples are too close ( 1sec) apart?

I only want time information on X-Axis. Please suggest how I can get that. Thanks in advance.

Update:

From comments, I am able to find the reason, why this is happening. Pandas is treating my Date and Time as timestamp object while for plotting it with Matplotlib, it should be datetime object. My problem will get solved if I am able to convert df['Time'] from Timestamp to datetime. I searched online and found the pd.to_datetime, will do this work for me, but unfortunately, it doesn't work. The following commands will list what I have done.

>>> x = pd.Timestamp( "2018-01-20")
>>> x
Timestamp('2018-01-20 00:00:00')
>>> pd.to_datetime( x, format="%Y-%m-%d")
Timestamp('2018-01-20 00:00:00')

As you can see above, i still get timestamp object I searched again to check why it is not working, then I found that the following line will work.

>>> x = pd.Timestamp( "2018-01-20")
>>> y = pd.to_datetime( x, format="%Y-%m-%d")
>>> y.to_datetime()

Warning (from warnings module):
  File "D:\Program Files\Python36\lib\idlelib\run.py", line 457
    exec(code, self.locals)
FutureWarning: to_datetime is deprecated. Use self.to_pydatetime()
datetime.datetime(2018, 1, 20, 0, 0)
>>> 

To remove this warning following commands can be used.

>>> x = pd.Timestamp( "2018-01-20")
>>> y = pd.to_datetime( x, format="%Y-%m-%d")
>>> y.to_pydatetime()
datetime.datetime(2018, 1, 20, 0, 0)

Now I tested these command in my project to see if this is working with my dataframe or not, I just took one value for testing.

>>> x = df['Time'][0].to_pydatetime()
>>> x
datetime.datetime(2018, 1, 20, 16, 8, 45)

So, yes it is working, now I have to apply this on complete column of dataframe and I used the following command.

>>> df['New'] = df['Time'].apply(lambda x: x.to_pydatetime())
>>> df['New'][0]
Timestamp('2018-01-20 16:08:45')

But it's still the same. I am newbie, so I am not able to understand what I am doing wrong.

Upvotes: 2

Views: 3530

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339052

First we need a minimal, verifiable example:

u = u"""16:08:45,64,31.2
16:08:46,54,29.3
16:08:47,36,34.3
16:08:48,67,36.3
16:08:49,87,29.3"""

import io
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

year = 2018
month = 1
date = 20

headers = ['Time', 'ADC', 'Temperature']

df = pd.read_table(io.StringIO(u), ',', names=headers,\
                        engine='python', header=None)

FMT = '%H:%M:%S'
df['Time'] = df['Time'].map(lambda x: datetime.strptime(str(x), FMT))
df['Time'] = df['Time'].map(lambda x: x.replace(day=date, month=month, year=year))

plt.plot( df['Time'], df['ADC'])

plt.ylim( [20,100])
plt.gcf().autofmt_xdate()
plt.show()

Running this code with pandas 0.20.1 and matplotlib 2.1, the following plot is produced, which looks as desired:

enter image description here

The reason this works, even if the dates are pandas time stamps is that matplotlib uses the pandas converters internally, if they are available. If not, one may first try to load them manually,

import pandas.plotting._converter as pandacnv
pandacnv.register()

If this also fails, one may indeed try to convert the timestamps to datetime objects.

dt = [x.to_pydatetime() for x in df['Time']]
plt.plot( dt, df['ADC'])

Upvotes: 2

Related Questions