matplotlibで日付が誤って表示される。

#1 この記事の説明

Pythonのplotを使い時系列グラフを描写したところ日付の変換が正しく動作しない。
例えば、2020-01-01が0051-01-01と誤って表示されてしまう。

<img width="695" alt="80.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/ff56276a-e14a-1dd1-bb3f-beec963a541d.jpeg">


#2 横軸の日付が誤って表示されるコード
Pandasで生成したデータフレームに関して「データフレーム.plot(・・・・)」のコマンドでグラフを表示し、「mdates.DateFormatter('%Y-%m-%d')」にて「フォーマットをY-M-Dにした場合、日にちが正しく表示されないことが分かった。下記のコードを実行すると横軸日付が正しく表示されない。

```python:/home/sampletest/sample.py
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import seaborn as sns

# Dataセットを定義する。(日付はdatetime.datetimeで記載する。日付型で表記する)
dat = [
    [datetime.datetime(2020,1,1),4,10],
    [datetime.datetime(2020,1,2),7,7],
    [datetime.datetime(2020,1,3),10,4],
    [datetime.datetime(2020,1,4),13,2],
    [datetime.datetime(2020,1,5),17,1],
    [datetime.datetime(2020,1,6),12,4],
    [datetime.datetime(2020,1,7),9,3],
    [datetime.datetime(2020,1,8),7,8],
    [datetime.datetime(2020,1,9),5,9],
    [datetime.datetime(2020,1,10),3,12],
    
    
]

dat=pd.DataFrame(dat,columns=["DATE","Y","Z"])
dat.set_index("DATE",inplace=True) #横軸に表示する日付をDataFrameのindexにする。
print(dat)


fig = sns.mpl.pyplot.figure() #グラフを描写するオブジェクトを生成する。
ax=dat.plot(marker="o",figsize=(15, 5)) #Dataframe.plotの形式でグラフを描写するとエラーになる
ax.legend() #凡例を描写する

# グラフのフォーマットの設定(横軸の日付の表示方法を設定する。)
days    = mdates.DayLocator(bymonthday=None, interval=2, tz=None)  # 横軸：「毎日」を表示対象にする。(この行がないと日付が重複表示される)
daysFmt = mdates.DateFormatter('%Y-%m-%d') #横軸：フォーマットをY-M-Dにする。
ax.xaxis.set_major_locator(days) #横軸に日付を表示する。
ax.xaxis.set_major_formatter(daysFmt) #横軸に日付を表示する。
fig.autofmt_xdate() #横軸の日付を見やすいように斜めにしてくれる。

# グラフに名前を付ける
ax.set_xlabel('Date') #X軸のタイトルを設定する
ax.set_ylabel('Y') #Y軸のタイトルを設定する
plt.title(r"TEST",fontname="MS Gothic")  #グラフのタイトルを設定する。日本語を指定するときは、fontnameの指定が必要
#グラフのサイズを設定する
fig.set_figheight(10)
fig.set_figwidth(20)
#横軸の表示範囲を設定する
ax.set_xlim(datetime.datetime(2020,1,1), datetime.datetime(2020,1,12)) 
```


#3 横軸の日付を正しく表示するコード

データフレームの日付の行を　datetimeからMatplotlib dateに変更する必要がある。

dat['DATE'] = mdates.date2num(dat['DATE']) を追加する。


```python:/home/sampletest/sample.py
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import seaborn as sns
import pandas as pd

# Dataセットを定義する。(日付はdatetime.datetimeで記載する。日付型で表記する)
dat = [
    [datetime.datetime(2020,1,1),4,10],
    [datetime.datetime(2020,1,2),7,7],
    [datetime.datetime(2020,1,3),10,4],
    [datetime.datetime(2020,1,4),13,2],
    [datetime.datetime(2020,1,5),17,1],
    [datetime.datetime(2020,1,6),12,4],
    [datetime.datetime(2020,1,7),9,3],
    [datetime.datetime(2020,1,8),7,8],
    [datetime.datetime(2020,1,9),5,9],
    [datetime.datetime(2020,1,10),3,12],
     
]

dat=pd.DataFrame(dat,columns=["DATE","Y","Z"])
dat['DATE'] = mdates.date2num(dat['DATE'])  #ここを追加する　Convert datetime objects to Matplotlib dates.
dat.set_index("DATE",inplace=True) #横軸に表示する日付をDataFrameのindexにする。
print(dat)


fig = sns.mpl.pyplot.figure() #グラフを描写するオブジェクトを生成する。
ax=dat.plot(marker="o",figsize=(15, 5))
ax.legend() #凡例を描写する

# グラフのフォーマットの設定(横軸の日付の表示方法を設定する。)
days    = mdates.DayLocator(bymonthday=None, interval=2, tz=None)  # 横軸：「毎日」を表示対象にする。(この行がないと日付が重複表示される)
daysFmt = mdates.DateFormatter('%Y-%m-%d') #横軸：フォーマットをY-M-Dにする。
ax.xaxis.set_major_locator(days) #横軸に日付を表示する。
ax.xaxis.set_major_formatter(daysFmt) #横軸に日付を表示する。
fig.autofmt_xdate() #横軸の日付を見やすいように斜めにしてくれる。

# グラフに名前を付ける
ax.set_xlabel('Date') #X軸のタイトルを設定する
ax.set_ylabel('Y') #Y軸のタイトルを設定する
plt.title(r"TEST",fontname="MS Gothic")  #グラフのタイトルを設定する。日本語を指定するときは、fontnameの指定が必要
#グラフのサイズを設定する
fig.set_figheight(10)
fig.set_figwidth(20)
#横軸の表示範囲を設定する
ax.set_xlim(datetime.datetime(2020,1,1), datetime.datetime(2020,1,12)) 
```

<img width="694" alt="81.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/b2b37f0e-75b5-8ab3-6eff-938e39b94d61.jpeg">