首页 > 解决方案 > Python matplotlib - 日期时间值系列中的无值

问题描述

我正在尝试绘制一系列日期。由于数据集不完整,该系列有一些 None 值,这会导致错误。

这篇文章成功地处理了一个类似的问题Python matplotlib - errorbar None values in series

但我无法将它应用于 datetime.date 值列表。

我的代码是

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

fig, ax1 = plt.subplots()

keys = ["a", "b", "c", "d"]
series_one = np.array(
    [
        datetime.date(2020, 11, 13),
        datetime.date(2021, 2, 28),
        datetime.date(2021, 3, 31),
        datetime.date(2021, 4, 30),
    ]
)
series_two = np.array(
    [
        datetime.date(2020, 11, 13),
        datetime.date(2021, 2, 28),
        datetime.date(2021, 3, 31),
        None,
    ]
)
series_three = np.array(
    [
        datetime.date(2020, 11, 13),
        None,
        datetime.date(2021, 3, 31),
        datetime.date(2020, 2, 1),
    ]
)

ax1.scatter(series_one, keys)
ax1.scatter(series_two, keys)
ax1.scatter(series_three, keys)

错误信息:

使用 NoneType 时

AttributeError: 'NoneType' object has no attribute 'toordinal

当使用 float("NaN") 而不是 None 时。

AttributeError: 'float' object has no attribute 'toordinal'

标签: pythonnumpymatplotlib

解决方案


这里的核心问题是您正在传递异构数据列表:datetime对象和None. 在您链接的问题中确实会发生同样的问题。这个问题可以解决,float('nan')因为float('nan')它是一个浮点元素,因此使列表中的所有元素都具有相同的类型。

很抱歉,但我认为您确实需要使用辅助函数手动删除 None 为

def do_mask(x,y):
    mask = None
    mask = ~(x == None)
    return np.array(x)[mask], np.array(y)[mask]

如下使用它

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

fig, ax1 = plt.subplots()

keys = ["a", "b", "c", "d"]
series_one = np.array(
    [
        datetime.date(2020, 11, 13),
        datetime.date(2021, 2, 28),
        datetime.date(2021, 3, 31),
        datetime.date(2021, 4, 30),
    ]
)
series_two = np.array(
    [
        datetime.date(2020, 11, 13),
        datetime.date(2021, 2, 28),
        datetime.date(2021, 3, 31),
    None    
    ]
)
series_three = np.array(
    [
        datetime.date(2020, 11, 13),
        None,
        datetime.date(2021, 3, 31),
               datetime.date(2021, 3, 31),

    ]
)



ax1.scatter(*do_mask(series_one, keys))
ax1.scatter(*do_mask(series_two, keys))
ax1.scatter(*do_mask(series_three, keys))

推荐阅读