re-grid/re-mesh unstructured 3D array data into a pre-existing grid

Viewed 266

I have a map of values for a specific grid:

X       Y       Z       Value
0.555   0.334   0.472   1.361
0.674   0.729   0.711   2.114
0.538   0.982   0.886   2.406
0.775   0.279   0.789   1.843
0.292   0.206   0.984   1.482

I would like to convert the values (using same kind of interpolation method) into a pre-existing grid:

X       Y       Z       NewValue    
0.721   0.824   0.974   
0.244   0.982   0.813   
0.239   0.288   0.961   
0.885   0.439   0.308   
0.344   0.006   0.554   

for example in 2D: the new values:

X       Y       Value
0.429   0.714   1.142
0.583   0.826   1.409
0.309   0.872   1.182
0.563   0.096   0.659
0.924   0.947   1.872

the old, pre-existing grid:

X       Y   
0.595   0.928   
0.426   0.800   
0.974   0.527   
0.864   0.398   
0.915   0.816   

the orange dots will be converted to the new blue dots.

enter image description here

Thanks in advance

2 Answers

OK found it.

First we need to make sure the the origins and/or the coordinates is the same.

Second,

import pandas
import numpy
import scipy

old_x = dfOld['X'].to_numpy()
old_y = dfOld['Y'].to_numpy()
old_z = dfOld['Z'].to_numpy()
oldValues = dfOld['Value'].to_numpy()

new_x = dfNew['x'].to_numpy()
new_y = dfNew['y'].to_numpy()
new_z = dfNew['z'].to_numpy()

dfLin = scipy.interpolate.griddata((old_x, old_y, old_z), oldValues, (new_x, new_y, new_z), method='linear')
dfNear = scipy.interpolate.griddata((old_x, old_y, old_z), oldValues, (new_x, new_y, new_z), method='nearest')
dfLin[numpy.isnan(dfLin)] = dfNear[numpy.isnan(dfLin)] 
final = np.concatenate([newGrid, dfLin], axis=1)

A good and easy way to interpolate is using radial basis functions. It works in 2 and 3 dimensions.

If you use Python and install a few modules like numpy, scipy and matplotlib (or use Anaconda instead, it carries all of them) then an implementation could look like this (not completely checked for correctness).

import numpy as np
from scipy.interpolate import Rbf
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
import matplotlib.cm as cm


# data read from csv files
source = 'source.csv'
target = 'target.csv'

# create a pandas dataframe for each file
# pandas used here so that a huge dataset can be handled easily
df = pd.read_csv(source, names=['xs', 'ys', 'zs', 'ts'])
df1 = pd.read_csv(target, names=['xt', 'yt', 'zt'])

# convert the data to numbers
xs = df['xs'].values
ys = df['ys'].values
zs = df['zs'].values
ts = df['ts'].values

xt = df1['xt'].values
yt = df1['yt'].values
zt = df1['zt'].values

# create a radial basis function interpolant
# works in 2D and 3D
rbf = Rbf(xs, ys, zs, ts)

# evaluate the interpolated function at the new locations
T = rbf(xt, yt, zt)

# plot the result
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# plot the newly interpolated points (bigger dots)
ax.scatter(xt, yt, zt, c=T, cmap=cm.jet, vmin=1.3, vmax=2.4, s=300)

# plot the original data (smaller dots)
ax.scatter(xs, ys, zs, c=ts, cmap=cm.jet, vmin=1.3, vmax=2.4, s=100)

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

enter image description here

Related