How to work with NaN value when plotting a chart using python?

I am using matplotlitb to plot the chart, but there are some missing values ​​(NaN). Then I found that the columns containing NaN values ​​are not showing the field value. Do you know how to fix this problem? Here are the codes.

import numpy as np
import matplotlib.pyplot as plt

#==============================================================================
# open data
#==============================================================================
filename='C:\\Users\\liren\\OneDrive\\Data\\DATA in the first field-final\\ks.csv'

AllData=np.genfromtxt(filename,delimiter=";",skip_header=0,dtype='str')

TreatmentCode = AllData[1:,0]
RepCode = AllData[1:,1]
KsData= AllData[1:,2:].astype('float')
DepthHeader = AllData[0,2:].astype('float')
TreatmentUnique = np.unique(TreatmentCode)[[3,1,4,2,8,6,9,7,0,5,10],]
nT = TreatmentUnique.size#nT=number of treatments
#nD=number of deepth;nR=numbers of replications;nT=number of treatments;iT=iterms of treatments
nD = 5
nR = 6
KsData_3D = np.zeros((nT,nD,nR)) 

for iT in range(nT):
    Treatment = TreatmentUnique[iT]

    TreatmentFilter = TreatmentCode == Treatment

    KsData_Filtered = KsData[TreatmentFilter,:]

    KsData_3D[iT,:,:] = KsData_Filtered.transpose()iD = 4

fig=plt.figure()
ax = fig.add_subplot(111)
plt.boxplot(KsData_3D[:,iD,:].transpose())
ax.set_xticks(range(1,nT+1))
ax.set_xticklabels(TreatmentUnique)
ax.set_title(DepthHeader[iD])

      

Here is the final figure and some of the treatments are missing.

enter image description here

+3


source to share


1 answer


You can remove NaN

from the data first and then filter the filtered data.

To do this, you can first find NaN

with np.isnan(data)

, then bitwise access that boolean array with the ~

operator
. Use this to index an array of data and you are filtering out NaN

s.

filtered_data = data[~np.isnan(data)]

      

In full example (adapted from here )

For 1D data:

import matplotlib.pyplot as plt
import numpy as np

# fake up some data
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low), 0)

# Add a NaN
data[40] = np.NaN

# Filter data using np.isnan
filtered_data = data[~np.isnan(data)]

# basic plot
plt.boxplot(filtered_data)

plt.show()

      



For 2D data:

For 2D data, you cannot just use the mask above as each column of the data array will have a different length. Instead, we can create a list, with each item in the list being filtered data for each column of the data array.

A list comprehension can do it in one line: [d[m] for d, m in zip(data.T, mask.T)]

import matplotlib.pyplot as plt
import numpy as np

# fake up some data
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low), 0)

data = np.column_stack((data, data * 2., data + 20.))

# Add a NaN
data[30, 0] = np.NaN
data[20, 1] = np.NaN

# Filter data using np.isnan
mask = ~np.isnan(data)
filtered_data = [d[m] for d, m in zip(data.T, mask.T)]

# basic plot
plt.boxplot(filtered_data)

plt.show()

      

I'll leave this as an exercise for the reader to extend it to 3 or more dimensions, but you get the idea.

+7


source







All Articles