Python 与 0.14 相比,使用 matplotlib 在 x 轴上绘制日期时间索引会在 Pandas 0.15 中创建错误的刻度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26526230/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Plotting datetimeindex on x-axis with matplotlib creates wrong ticks in pandas 0.15 in contrast to 0.14
提问by Dirk
I create a simple pandas dataframe with some random values and a DatetimeIndex like so:
我创建了一个简单的 Pandas 数据框,其中包含一些随机值和一个 DatetimeIndex,如下所示:
import pandas as pd
from numpy.random import randint
import datetime as dt
import matplotlib.pyplot as plt
# create a random dataframe with datetimeindex
dateRange = pd.date_range('1/1/2011', '3/30/2011', freq='D')
randomInts = randint(1, 50, len(dateRange))
df = pd.DataFrame({'RandomValues' : randomInts}, index=dateRange)
Then I plot it in two different ways:
然后我以两种不同的方式绘制它:
# plot with pandas own matplotlib wrapper
df.plot()
# plot directly with matplotlib pyplot
plt.plot(df.index, df.RandomValues)
plt.show()
(Do not use both statements at the same time as they plot on the same figure.)
(不要同时使用这两个语句,因为它们绘制在同一图上。)
I use Python 3.4 64bitand matplotlib 1.4. With pandas 0.14, both statements give me the expected plot (they use slightly different formatting of the x-axis which is okay; note that data is random so the plots do not look the same):

我使用Python 3.4 64bit和matplotlib 1.4。使用pandas 0.14,这两个语句都给了我预期的图(它们使用的 x 轴格式略有不同,这是可以的;请注意,数据是随机的,因此图看起来不一样):



However, when using pandas 0.15, the pandas plot looks alright but the matplotlib plot has some strange tick format on the x-axis:
但是,当使用pandas 0.15 时,pandas 图看起来不错,但 matplotlib 图在 x 轴上有一些奇怪的刻度格式:




Is there any good reason for this behaviour and why it has changed from pandas 0.14 to 0.15?
这种行为有什么好的理由吗?为什么它从 pandas 0.14 变为 0.15?
采纳答案by joris
Note that this bug was fixed in pandas 0.15.1 (https://github.com/pandas-dev/pandas/pull/8693), and plt.plot(df.index, df.RandomValues)now just works again.
请注意,此错误已在 pandas 0.15.1 ( https://github.com/pandas-dev/pandas/pull/8693) 中修复,plt.plot(df.index, df.RandomValues)现在又可以正常工作了。
The reason for this change in behaviour is that starting from 0.15, the pandas Indexobject is no longer a numpy ndarray subclass. But the real reasonis that matplotlib does not support the datetime64dtype.
这种行为变化的原因是从 0.15 开始,pandasIndex对象不再是 numpy ndarray 子类。但真正的原因是 matplotlib 不支持datetime64dtype。
As a workaround, in the case you want to use the matplotlib plotfunction, you can convert the index to python datetime's using to_pydatetime:
作为一种解决方法,如果您想使用 matplotlibplot函数,您可以使用以下命令将索引转换为 python 日期时间to_pydatetime:
plt.plot(df.index.to_pydatetime(), df.RandomValues)
More in detail explanation:
更详细的解释:
Because Indexis no longer a ndarray subclass, matplotlib will convert the index to a numpy array with datetime64dtype (while before, it retained the Indexobject, of which scalars are returned as Timestampvalues, a subclass of datetime.datetime, which matplotlib can handle). In the plotfunction, it calls np.atleast_1d()on the input which now returns a datetime64 array, which matplotlib handles as integers.
因为Index不再是 ndarray 子类,matplotlib 会将索引转换为带有 dtype 的 numpy 数组datetime64(而之前,它保留了Index对象,其中标量作为Timestamp值返回,是 的子类datetime.datetime,matplotlib 可以处理)。在plot函数中,它调用np.atleast_1d()现在返回一个 datetime64 数组的输入,matplotlib 将其作为整数处理。
I opened an issue about this (as this gets possibly a lot of use): https://github.com/pydata/pandas/issues/8614
我打开了一个关于这个的问题(因为这可能有很多用途):https: //github.com/pydata/pandas/issues/8614
回答by tacaswell
With matplotlib 1.5.0 this 'just works':
使用 matplotlib 1.5.0,这“有效”:
import pandas as pd
from numpy.random import randint
import datetime as dt
import matplotlib.pyplot as plt
# create a random dataframe with datetimeindex
dateRange = pd.date_range('1/1/2011', '3/30/2011', freq='D')
randomInts = randint(1, 50, len(dateRange))
df = pd.DataFrame({'RandomValues' : randomInts}, index=dateRange)
fig, ax = plt.subplots()
ax.plot('RandomValues', data=df)

