首页 > 解决方案 > 在 x 轴上绘制格式化为月-年的 pandas 数据帧索引

问题描述

例如,我有一个数据框,我希望 x 轴显示为 APR-2018。ax.format_xdata 行不能解决问题。

import datetime as dt
import pandas as pd
import time
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

data = {("IVOG",1493510400000):{"Adj_Close":119.2136,"MA(3)":119.2136,"EWMA(3)":119.2136},
        ("IVOG",1496188800000):{"Adj_Close":120.8236,"MA(3)":120.0186,"EWMA(3)":120.0454},
        ("IVOG",1498780800000):{"Adj_Close":120.2736,"MA(3)":120.1036,"EWMA(3)":120.1266},
        ("IVOG",1501459200000):{"Adj_Close":121.7836,"MA(3)":120.5236,"EWMA(3)":120.5832},
        ("IVOG",1504137600000):{"Adj_Close":120.3536,"MA(3)":120.4896,"EWMA(3)":120.5309},
        ("IVOG",1506729600000):{"Adj_Close":124.3336,"MA(3)":121.1303,"EWMA(3)":121.2749}}

df=pd.DataFrame.from_dict(data, orient = 'index')
print(df)
ax = plt.gca()      # get current axis
df.plot(kind='line',y='Adj_Close', ax=ax)
df.plot(kind='line',y='MA(3)',ax=ax)
df.plot(kind='line',y='EWMA(3)', color='green', ax=ax)
print(df.index[0][1])
ax.format_xdata = mdates.DateFormatter('%b-%Y')     # Trying to get APR-2018
plt.xlabel(df.index[0][0])     # Trying to Get the Ticker
_=plt.grid()
_=plt.xticks(rotation=90)
plt.show()

第二个索引应该只是日期而不是时间,但它错误地绘制如下:Incorrect Plot

标签: pythonpandasdatetimematplotlib

解决方案


这应该可以解决问题。当然有“更漂亮”的方法,但我试图做到这一点,以便您可以使您的数据和原始数据框与您问题中的原始数据框尽可能接近。

评论后编辑:那怎么样,只需创建一个新列,其中包含您想要格式化的任何形状的日期。然后使用set_xticklabels()传递该列以根据需要设置刻度。此外,您可能希望删除默认 plt.xlabel (否则您将在 xticks 下方显示索引名称)。

import datetime as dt
import pandas as pd
import time
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# the first part of your code is the same
data = {("IVOG",1493510400000):{"Adj_Close":119.2136,"MA(3)":119.2136,"EWMA(3)":119.2136},
    ("IVOG",1496188800000):{"Adj_Close":120.8236,"MA(3)":120.0186,"EWMA(3)":120.0454},
    ("IVOG",1498780800000):{"Adj_Close":120.2736,"MA(3)":120.1036,"EWMA(3)":120.1266},
    ("IVOG",1501459200000):{"Adj_Close":121.7836,"MA(3)":120.5236,"EWMA(3)":120.5832},
    ("IVOG",1504137600000):{"Adj_Close":120.3536,"MA(3)":120.4896,"EWMA(3)":120.5309},
    ("IVOG",1506729600000):{"Adj_Close":124.3336,"MA(3)":121.1303,"EWMA(3)":121.2749}}

df=pd.DataFrame.from_dict(data, orient = 'index')

# first let's give a name to the indexes
df.index.names = ['ivog', 'timestamp']

# then create a new column with a datetime object
# (formatted to microseconds as your data seems to be)
df['date'] = pd.to_datetime(df.index.levels[1], 
unit='ms')

# now let's change the date to the format you want
df['date'] = df['date'].apply(lambda x: x.strftime("%Y %B"))


print(df)

# plot the data just like you were doing
ax = plt.gca()      # get current axis
df.plot(kind='line',y='Adj_Close', ax=ax)
df.plot(kind='line',y='MA(3)',ax=ax)
df.plot(kind='line',y='EWMA(3)', color='green', ax=ax)

# Now the x-axis label should be what you wished for
ax.set_xticklabels(df['date'])
plt.xlabel('Your x axis label') 
plt.ylabel('Your y axis label')
plt.title('My Awseome Plot')
plt.xticks(rotation=45)

推荐阅读