[英]Stackplot “TypeError: ufunc 'isfinite' not supported for the input types”
[英]MatPlotLib, datetimes, and TypeError: ufunc 'isfinite' not supported for the input types…
这是一小段代码,它在图形的两条线之间生成一个填充区域:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0.0, 2, 0.01)
y1 = np.sin(2 * np.pi * x)
y2 = 1.2 * np.sin(4 * np.pi * x)
fig, ax1 = plt.subplots(1, 1, sharex=True)
# Test support for masked arrays.
ax1.fill_between(x, 0, y1)
ax1.set_ylabel('between y1 and 0')
y2 = np.ma.masked_greater(y2, 1.0)
ax1.plot(x, y1, x, y2, color='black')
ax1.fill_between(
x, y1, y2, where=y2 >= y1,
facecolor='green',
interpolate=True)
ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True)
ax1.set_title('Now regions with y2>1 are masked')
# Show the plot.
plt.show()
它看起来像这样:
现在,更改开始,以便x
现在是日期时间对象的集合,如下所示:
import datetime
x1 = np.arange(0.0, 2, 0.01)
now = np.datetime64(datetime.datetime.now())
x = np.array([now - np.timedelta64(datetime.timedelta(seconds=i)) for i in range(200)])
y1 = np.sin(2 * np.pi * x1)
y2 = 1.2 * np.sin(4 * np.pi * x1)
产量:
Traceback (most recent call last): File "fill_between_demo.py", line 21, in <module>
ax1.fill_between(x, 0, y1)
File "/home/usr/.virtualenvs/raiju/lib/python3.6/site-packages/matplotlib/__init__.py", line 1898, in inner
return func(ax, *args, **kwargs)
File "/home/usr/.virtualenvs/raiju/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 4778, in fill_between
x = ma.masked_invalid(self.convert_xunits(x))
File "/home/usr/.virtualenvs/raiju/lib/python3.6/site-packages/numpy/ma/core.py", line 2388, in masked_invalid
condition = ~(np.isfinite(a))
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
为什么会发生这种情况以及如何解决它?
请注意,绘制数据(也就是不使用fill*
)效果很好。
问题是,numpy isfinite
没有为numpy.datetime64
定义。 不过,我们正在努力改变这一点。 numpy 的 github 上的这个问题正在这个pull-request 中处理,但只要这还没有完成和合并,你就不能在那个isfinite
上使用isfinite
。 这是一个问题,因为当调用numpy.ma.masked_invalid
来屏蔽输入数组的所有无效条目时, matplotlib.pyplot.fill_between
正在隐式使用此函数。
不过有一个解决方法。 正如在这个关于datetime64
类型的fill_between
Series
的fill_between
绘图的类似问题的回答中指出的那样,pandas 使用 matplotlib 为(除其他外) datetime64
dtype 的 numpy 数组注册了一个自定义转换器。 要使用它,您只需导入熊猫:
import numpy as np
import matplotlib.pyplot as plt
import datetime
# import pandas for its converter that is then used in pyplot!
import pandas
x1 = np.arange(0.0, 2, 0.01)
now = np.datetime64(datetime.datetime.now())
x = np.array([now - np.timedelta64(datetime.timedelta(seconds=i))
for i in range(200)])
y1 = np.sin(2 * np.pi * x1)
y2 = 1.2 * np.sin(4 * np.pi * x1)
fig, ax1 = plt.subplots(1, 1, sharex=True)
# Test support for masked arrays.
ax1.fill_between(x, 0, y1)
ax1.set_ylabel('between y1 and 0')
y2 = np.ma.masked_greater(y2, 1.0)
ax1.plot(x, y1, x, y2, color='black')
ax1.fill_between(
x, y1, y2, where=y2 >= y1,
facecolor='green',
interpolate=True)
ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True)
ax1.set_title('Now regions with y2>1 are masked')
# Show the plot.
plt.show()
将工作并为您提供所需的输出:
我对 ax.setxlims 有类似的问题,因为我忘记将一些日期时间转换为 np.datetime。
>>> import datetime
>>> import numpy
>>> a = datetime.datetime.now()
>>> numpy.isfinite(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
>>> a = numpy.datetime64(a)
>>> numpy.isfinite(a)
True
好像不再需要导入pandas了
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.