如何将日期数组传递给 pcolor 图?

How to pass date array to pcolor plot?

我有矩阵数据,其中一个轴与日期相关。但是,我在将此数据作为轴传递给 pcolor 时遇到问题。我的虚拟数据如下:

In [219]: X = [datetime.date.today() + datetime.timedelta(days=i) for i in range(4)]

In [220]: Y = arange(5)

In [221]: Z = arange(4*5).reshape(4, 5)

天真的尝试 pcolor(Y, X, Z) 失败了,因为 pcolor 不喜欢获取 list 对象:

In [222]: pcolor(Y, X, Z)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-222-1ece18b4bc13> in <module>()
----> 1 pcolor(Y, X, Z)

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/pyplot.py in pcolor(*args, **kwargs)
   2926         ax.hold(hold)
   2927     try:
-> 2928         ret = ax.pcolor(*args, **kwargs)
   2929         draw_if_interactive()
   2930     finally:

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/axes.py in pcolor(self, *args, **kwargs)
   7545         shading = kwargs.pop('shading', 'flat')
   7546 
-> 7547         X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False)
   7548         Ny, Nx = X.shape
   7549 

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/axes.py in _pcolorargs(funcname, *args, **kw)
   7357 
   7358         Nx = X.shape[-1]
-> 7359         Ny = Y.shape[0]
   7360         if len(X.shape) != 2 or X.shape[0] == 1:
   7361             x = X.reshape(1, Nx)

AttributeError: 'list' object has no attribute 'shape'

将其转换为包含 datetime.datearray 失败并显示 TypeError: float() argument must be a string or a number, not 'datetime.date':

In [223]: pcolor(Y, numpy.array(X), Z)                                                                                                                                 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-223-a00423a6d479> in <module>()
----> 1 pcolor(Y, numpy.array(X), Z)

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/pyplot.py in pcolor(*args, **kwargs)
   2926         ax.hold(hold)
   2927     try:
-> 2928         ret = ax.pcolor(*args, **kwargs)
   2929         draw_if_interactive()
   2930     finally:

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/axes.py in pcolor(self, *args, **kwargs)
   7606             kwargs['antialiaseds'] = False
   7607 
-> 7608         collection = mcoll.PolyCollection(verts, **kwargs)
   7609 
   7610         collection.set_alpha(alpha)

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/collections.py in __init__(self, verts, sizes, closed, **kwargs)
    743         Collection.__init__(self, **kwargs)
    744         self._sizes = sizes
--> 745         self.set_verts(verts, closed)
    746 
    747     def set_verts(self, verts, closed=True):

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/collections.py in set_verts(self, verts, closed)
    763                     codes[0] = mpath.Path.MOVETO
    764                     codes[-1] = mpath.Path.CLOSEPOLY
--> 765                     self._paths.append(mpath.Path(xy, codes))
    766                 else:
    767                     self._paths.append(mpath.Path(xy))

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/path.py in __init__(self, vertices, codes, _interpolation_steps, closed, readonly)
    131             vertices = vertices.astype(np.float_).filled(np.nan)
    132         else:
--> 133             vertices = np.asarray(vertices, np.float_)
    134 
    135         if codes is not None:

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/numpy/core/numeric.py in asarray(a, dtype, order)
    460 
    461     """
--> 462     return array(a, dtype, copy=False, order=order)
    463 
    464 def asanyarray(a, dtype=None, order=None):

TypeError: float() argument must be a string or a number, not 'datetime.date'

最后,将其转换为适当的 numpy.datetime64 对象也不能解决问题,失败 Invalid type promotion:

In [224]: pcolor(Y, numpy.array(X, dtype="datetime64[D]"), Z)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-224-0ac06cfafa35> in <module>()
----> 1 pcolor(Y, numpy.array(X, dtype="datetime64[D]"), Z)

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/pyplot.py in pcolor(*args, **kwargs)
   2926         ax.hold(hold)
   2927     try:
-> 2928         ret = ax.pcolor(*args, **kwargs)
   2929         draw_if_interactive()
   2930     finally:

/export/data/home/gholl/venv/gerrit/lib/python3.4/site-packages/matplotlib/axes.py in pcolor(self, *args, **kwargs)
   7577                              X4[:, newaxis], Y4[:, newaxis],
   7578                              X1[:, newaxis], Y1[:, newaxis]),
-> 7579                              axis=1)
   7580         verts = xy.reshape((npoly, 5, 2))
   7581 

TypeError: invalid type promotion

在这里进行的正确方法是什么?在

请注意 the question plotting date data with pcolor 的答案使用 scatter,而不是 pcolor,因此对我的情况没有帮助。

Matplotlib 使用简单的浮点数来表示日期时间。因此,您必须先转换它们,然后告诉轴必须将标签格式化为日期。 Matplotlib 为此提供了函数 date2num

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
import numpy as np

# Your original data (with adapted sizes)
x = [datetime.date.today() + datetime.timedelta(days=i) for i in range(4)]
y = np.arange(5)
z = np.arange(3*4).reshape(3, 4).T

# Convert to numbers
x = mdates.date2num(x)

# Create the figure
fig, ax = plt.subplots(1,1)
plt.pcolor(x,y,z)

# Setup the DateFormatter for the x axis
date_format = mdates.DateFormatter('%D')
ax.xaxis.set_major_formatter(date_format)

# Rotates the labels to fit
fig.autofmt_xdate()

plt.show()

其他一些备注:

  • 对于 pcolor,x 和 y 向量表示图块的角点。所以它们需要比数据长 1 个元素。
  • documentation 很好地概述了如何在 matplotlib 中处理日期。

结果: