Bertrand
Bertrand

Reputation: 101

Datetime issue with matplotlib

I'm pulling my hair to display a series with matplotlib.

I'm working with python 2.7. I have a pandas Dataframe with dates. I converted dates to datetime and I'm trying to display a plot without success.

import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, date

#I imported df before

type(df)
<class 'pandas.core.frame.DataFrame'>

# The dataframe
AnneeObs  MoisObs  JourObs  NbFluxEntrant
0        2019        8       19            763
1        2019        8        1           1098
...        ...      ...      ...            ...
655      2017       11        1            428
656      2017       11       13           1530

[657 rows x 4 columns]

# To convert dates to datetime
for i in range(0,len(df)):
     df.loc[i,"dateObs"] = date(year=df.iloc[i,0], month=df.iloc[i,1], 
day=df.iloc[i,2])

df['dateObs'] = pd.DatetimeIndex(df['dateObs'])

# To order by dates
df = df.sort_values("dateObs", ascending=True)

df2 = df[["dateObs", "NbFluxEntrant"]]

df2bis = df2.copy()
df2bis = df2bis.set_index('dateObs')

df2bis

# The new dataframe
            NbFluxEntrant
dateObs                  
2017-11-01            428
2017-11-02            931
...                   ...
2019-08-18            243
2019-08-19            763

[657 rows x 1 columns]

# Maybe it's too much...
df2bis.index = pd.to_datetime(df2bis.index)

type(df2bis.index)
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

# I tried to display it but...
df2bis.plot()

However, it doesn't work :

Fail to execute line 1: df2bis.plot()
ValueError: view limit minimum 0.0 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units

I tried others code but nothing good :

df2bis.plot(x="dateObs", y="NbFluxEntrant")
df2bis.plot(x=df2bis.index.values, y="NbFluxEntrant")

Do you have any suggestions ?

Thanks in advance

EDIT : I tried another code that doesn't work :

import matplotlib

dates = matplotlib.dates.date2num(df2bis.index)
dates

array([736634., 736635.,..., 737289., 737290.])

matplotlib.pyplot.plot_date(dates, df2bis["NbFluxEntrant"])

ValueError: view limit minimum 0.0 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units

Hmmm...

Upvotes: 10

Views: 32357

Answers (5)

sophie
sophie

Reputation: 49

There are missing values between the datetimes.

idx = pd.date_range(pd.to_datetime(first_month).item(), pd.to_datetime(last_month).item(), freq='MS')

data = data.reindex(idx)

Upvotes: -1

Anastasia Vishnyakova
Anastasia Vishnyakova

Reputation: 179

Try clearing your previous plot settings with plt.close(). This solved my issue.

Upvotes: 10

Deeksha
Deeksha

Reputation: 213

I faced a similar issue. You could try this:

df2bis.set_index('dateObs', inplace=True)
df2bis.index = pd.to_datetime(df2bis.index)
df2bis.plot()

Upvotes: 11

evanwoods
evanwoods

Reputation: 79

As others could not reproduce this ValueError, my guess is that you transformed df2bis to a pandas.Series somewhere and tried to plot the Series, that would throw:

ValueError: view limit minimum 0.0 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units

To fix this, try

pd.DataFrame(df2bis).plot()

Good luck!

Upvotes: -1

Sinth0ras
Sinth0ras

Reputation: 11

As i am not able to reproduce the error with the given code i can only guess what causing this issue. The most common one will be fixed as follows:

One possible reason for your error could be the fact that matplotlib doesn't like the datetime64 datatype. if you replace:

df2bis.plot()

with

plt.plot(df2bis.index.to_pydatetime(), df2bis.NbFluxEntrant)

that should be fixed.

The other option are NaN inside your DataFrame so drop all NaN before plotting

plt.plot(df2bis.index.to_pydatetime().dropna(), df2bis.NbFluxEntrant.dropna())

Another poitn that could cause the issue is that soemthing goes wrong with the default format. Just make sure you add the format to_datetime otherwise it could change up day and month

df2bis.index = pd.to_datetime(df2bis.index, format="%Y-%m-%d")

Upvotes: 0

Related Questions