【问题标题】:Python matplotlib - None values in series of datetime valuesPython matplotlib - 日期时间值系列中的无值
【发布时间】:2020-12-02 21:51:05
【问题描述】:

我正在尝试绘制一系列日期。由于数据集不完整,该系列有一些 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'

【问题讨论】:

  • 似乎 None 为我返回了 1680 年,你也一样吗?
  • 您希望在最终结果中看到什么来代替 None?
  • @ombk 由于 None 值,我刚刚崩溃。谢谢。

标签: python numpy matplotlib


【解决方案1】:

由于您将它们绘制为散点图,因此顺序并不重要。您可以为非零元素索引ndarrays:

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

series_one = np.array(
    [
        datetime.date(2020, 11, 13),
        datetime.date(2021, 2, 28),
        None,
        datetime.date(2021, 4, 30),
    ]
)

idx = series_one.nonzero()[0].tolist()
plt.scatter(series_one[idx], np.array(keys)[idx])

由于这是 numpy 的一项功能,因此您需要在切片之前将列表 keys 转换为 ndarraynp.array(keys)[idx]

【讨论】:

    【解决方案2】:

    这里的核心问题是您正在传递异构数据列表: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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-01
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多