时间序列绘制Pandas中的不一致性

Ame*_*ina 5 python matplotlib pandas

说我有一个数据帧df,其中df.index包含的datetime对象,例如

> df.index[0]
datetime.date(2014, 5, 5)
Run Code Online (Sandbox Code Playgroud)

如果我绘制它,Pandas很好地保留了datetime绘图中的类型,这允许用户更改时间序列采样以及绘图的格式选项:

  # Plot the dataframe:
  f     = plt.figure(figsize=(8,8))
  ax    = f.add_subplot(1,1,1)
  lines = df.plot(ax=ax)

  # Choose the sampling rate in terms of dates:
  ax.xaxis.set_major_locator(matplotlib.dates.WeekdayLocator(byweekday=(0,1,2,3,4,5,6),
                                                            interval=1))

  # We can also re-sample the X axis numerically if we want (e.g. every 4 steps):
  N = 4

  ticks      = ax.xaxis.get_ticklocs()
  ticklabels = [l.get_text() for l in ax.xaxis.get_ticklabels()]

  ax.xaxis.set_ticks(ticks[-1::-N][::-1])
  ax.xaxis.set_ticklabels(ticklabels[-1::-N][::-1])

  # Choose a date formatter using a date-friendly syntax:
  ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%b\n%d'))

  plt.show()
Run Code Online (Sandbox Code Playgroud)

然而,上述没有为工作boxplot(刻度标签x轴被渲染为空):

df2.boxplot(column='A', by='created_dt',ax=ax, sym="k.")

# same code as above ...
Run Code Online (Sandbox Code Playgroud)

看起来在最后一个例子中,Pandas将x轴标签转换为字符串类型,因此格式化程序和定位器不再起作用.

这篇文章重用了以下主题的解决方案:

  1. Pandas timeseries绘图设置x轴主要和次要刻度和标签的接受答案
  2. Pandas接受的答案:bar plot xtick frequency

为什么?如何boxplot以允许我使用matplotlib日期定位器和格式化程序的方式使用?

CT *_*Zhu 6

不,实际上连线图都没有正常工作,如果你有年份出现,你会注意到问题:在下面的例子中,不是2000,xticks是在1989年.

In [49]:
df=pd.DataFrame({'Val': np.random.random(50)})
df.index=pd.date_range('2000-01-02', periods=50)
f     = plt.figure()
ax    = f.add_subplot(1,1,1)
lines = df.plot(ax=ax)
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%y%b\n%d'))
print ax.get_xlim()
(10958.0, 11007.0)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

In [50]:
matplotlib.dates.strpdate2num('%Y-%M-%d')('2000-01-02')
Out[50]:
730121.0006944444
In [51]:
matplotlib.dates.num2date(730121.0006944444)
Out[51]:
datetime.datetime(2000, 1, 2, 0, 1, tzinfo=<matplotlib.dates._UTC object at 0x051FA9F0>)
Run Code Online (Sandbox Code Playgroud)

原来datetime数据在不同的处理pandasmatplotlib:在后者,2000-1-2应该是730121.0006944444,而不是10958.0pandas

要做到正确,我们需要避免使用pandasplot方法:

In [52]:
plt.plot_date(df.index.to_pydatetime(), df.Val, fmt='-')
ax=plt.gca()
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%y%b\n%d'))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

同样地barplot:

In [53]:
plt.bar(df.index.to_pydatetime(), df.Val, width=0.4)
ax=plt.gca()
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%y%b\n%d'))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • @ user815423426,这是一个旧问题,请参见相关(旧)帖子:http://stackoverflow.com/questions/12945971/pandas-timeseries-plot-setting-x-axis-major-and-minor-ticks-和标签。正如您所看到的那样,我一直在努力将其视为错误,或者不认为它是错误,这归结为以下事实:`pandas.tseries.index.DatetimeIndex`和`datetime.datetime`完全不同。我个人认为`pandas`plot`方法用于仅按原样使用时生成图。如果要进行自定义,我宁愿直接使用`matplotlib`。功能请求可能会有所帮助。干杯! (2认同)