0

I am trying to plot a series of dates. Due to an incomplete data set the series have some None values, which cause an error.

This post deals with a similar issue successfully Python matplotlib - errorbar None values in series

But I have not been able to apply it to a list of datetime.date values.

My code is

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)

The error message:

when using NoneType

AttributeError: 'NoneType' object has no attribute 'toordinal

when using float("NaN") istead of None.

AttributeError: 'float' object has no attribute 'toordinal'
3
  • 1
    seems like the None is returning a year 1680 for me, are u getting the same? Commented Dec 1, 2020 at 12:24
  • what would you like to see in the place of the None in the final result? Commented Dec 1, 2020 at 13:16
  • @ombk I just get a crash due to the None value. Thanks. Commented Dec 2, 2020 at 12:22

2 Answers 2

1

Since your are plotting them as a scatter plot, the order is not crucial. You could index the ndarrays for non-zero elements:

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])

Since this is a feature from numpy, you need to convert the list keys to an ndarray before slicing: np.array(keys)[idx]

result

Sign up to request clarification or add additional context in comments.

Comments

1

The core problem here is that you are passing heterogeneous list of data: datetime objects and None. It is ture that the same problem happens in the question that you linked. That problem can be solved with float('nan') because float('nan') is a floating point element thus making all elements in the list of the same kind.

I am sorry but I think you do ned to remove the None by hand with an helper function as

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

Use it as follows

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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.