3

I'm trying to write a very simple piece of code that will interpolate from a set of existing data to create a synthetic distribution of values.

The code I have so far looks like this:

import pandas as pd
import numpy as np
import scipy
from scipy.interpolate import griddata
import matplotlib

CRN_data=pd.read_table('disequilibrium data.dat',sep=',')
kzz=CRN_data['Kzz']
temperature=CRN_data['Temperature']
degree=CRN_data['Mean Degree']
points=np.ndarray(shape=(len(kzz),2),dtype='float')
for i in range(len(kzz)):
    points[i][0]=kzz[i]
    points[i][1]=temperature[i]
gridx,gridy= np.mgrid[0:1:100j,0:1:200j]
grid=griddata(points,degree,(gridx,gridy),method='cubic')
print grid

And the dataset I'm interpolating from looks like this:

Kzz,Temperature,Mean Degree,   
1.00E+06,400,7.41E+18
1.00E+06,500,4.48E+23
...
1.00E+08,400,4.67E+18
1.00E+08,500,6.88E+23
1.00E+08,750,1.88E+34
...
1.00E+10,750,2.73E+33
1.00E+10,900,2.82E+37
1.00E+10,1000,1.19E+39
...

However, while the code runs, the major output I get is

[[ nan  nan  nan ...,  nan  nan  nan]
 [ nan  nan  nan ...,  nan  nan  nan]
 [ nan  nan  nan ...,  nan  nan  nan]
 ..., 
 [ nan  nan  nan ...,  nan  nan  nan]
 [ nan  nan  nan ...,  nan  nan  nan]
 [ nan  nan  nan ...,  nan  nan  nan]]

which obviously isn't very helpful. Is this a bug within Scipy, or (more likely) am I doing something wrong?

Tessa
  • 79
  • 1
  • 11

2 Answers2

2

You are receiving nan values because your requested points contained in gridx and gridy are outside of the convex hull of the input points in points. You could specify a fill_value to use for extrapolated points, but you might think about re-specifying your allocated limits for gridx and gridy to produce meaningful results, such as:

import pandas as pd
import numpy as np
from scipy.interpolate import griddata
import matplotlib.pyplot as plt

CRN_data = pd.DataFrame([
[1.00E+06,400,7.41E+18],
[1.00E+06,500,4.48E+23],
[1.00E+08,400,4.67E+18],
[1.00E+08,500,6.88E+23],
[1.00E+08,750,1.88E+34],
[1.00E+10,750,2.73E+33],
[1.00E+10,900,2.82E+37],
[1.00E+10,1000,1.19E+39]],
columns=['Kzz','Temperature','Mean Degree'])

kzz = CRN_data['Kzz']
temperature = CRN_data['Temperature']
degree = CRN_data['Mean Degree']

points = np.matrix([[kzz[i], temperature[i]] for i in range(len(kzz))])

gridx, gridy = np.mgrid[kzz.min():kzz.max():100j,temperature.min():temperature.max():200j]

grid = griddata(points, degree, (gridx, gridy), method='cubic')

Yields:

[[7.41000000e+18 1.35147259e+22 2.70220418e+22 ...            nan
             nan            nan]
 [           nan 1.07878728e+33 1.26216288e+33 ...            nan
             nan            nan]
 [           nan            nan 1.38255505e+35 ...            nan
             nan            nan]
 ...
 [           nan            nan            nan ... 1.16569048e+39
             nan            nan]
 [           nan            nan            nan ... 1.16394396e+39
  1.17798560e+39            nan]
 [           nan            nan            nan ... 1.16129655e+39
  1.17564827e+39 1.19000000e+39]]

And plotting:

enter image description here

rahlf23
  • 8,869
  • 4
  • 24
  • 54
0

Compare the ranges of the source data with your target grid. From what I see the source ranges x=1e6:1e10 and y=400:1000 while your grid is 0-1 (both x and y). In this case the 'target' is outside the source data and using 'linear' or 'cubic' will give you NaN - try the 'nearest' and Nan's will disappear.

piotrt75
  • 11
  • 2