如何将日期数组传递给 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.date
的 array
失败并显示 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 中处理日期。
结果:
我有矩阵数据,其中一个轴与日期相关。但是,我在将此数据作为轴传递给 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.date
的 array
失败并显示 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 中处理日期。
结果: