pythonlistnumpymatplotlib

Why can I plot data arrays containing None values when using numpy array, but not when using list?


I have some data, X and Y, which I'd like to plot simply as X vs Y.

However, for some elements of Y, there is no data. I record this as None rather than 0, since matplotlib helpfully does not plot it (I don't want to draw a line down to zero and back).

I noticed this works if I do:

import numpy as np
import matplotlib.pyplot as plt
X = np.array([1,2,3,4])
Y = np.array([1,2,3,None])
Y_ERR = np.array([1,1,1,None])
plt.errorbar(X, Y, yerr = Y_ERR)
plt.show()

However, when I use lists instead, I get the error:

X = [1,2,3,4]
Y = [1,2,3,None]
plt.errorbar(X, Y, yerr = Y_ERR)
plt.show()

TypeError: unsupported operand type(s) for -: 'NoneType' and 'NoneType'

I have also realised if I use .tolist() function on the numpy arrays inside the plt.errorbar function, the error does not occur, when I imagine this should be equivalent to using lists. E.G.:

X = np.array([1,2,3,4])
Y = np.array([1,2,3,None])
Y_ERR = np.array([1,1,1,None])
plt.errorbar(X.tolist(), Y.tolist(), yerr = Y_ERR.tolist())
plt.show()

Why is this the case?


Solution

  • I think numpy treats None as an object dtype array automatically, since generally None is not a valid value in numerical arrays. When you use tolist() numpy also helps with the conversion and turns None values into np.nan (Not A Number), which is a valid numerical value.

    You can use np.nan in your lists instead of None:

    import numpy as np
    import matplotlib.pyplot as plt
    
    X = [1, 2, 3, 4]
    Y = [1, 2, 3, np.nan]
    Y_ERR = [1, 1, 1, np.nan] 
    
    plt.errorbar(X, Y, yerr=Y_ERR)
    plt.show()
    

    Matplotlib will still not plot it and you will not get the unsupported operand type error.