Search code examples
pythonscipyinterpolationdata-analysis

Extracting interpolated data along a line between 2 points of a scalar located at nodes of a 2-D unstructured mesh


I have a csv of data in the following form:

x-coordinate y-coordinate scalar
0 0 0.2344
0.1 0.25 12.588
... ... ...
0.65 0.8 0.4438
1 1 12.5

This data is from a simulation performed on an unstructured grid.

I want to define 2 points p1 & p2, and extract the scalar values along a line drawn between p1 & p2.

My p1 and p2 will be picked in such a way that either the x or the y will remain constant along the line, (the lines will always be longitudinal or latitudinal: example: p1(x=0, y=0.5) & p2(x=1, y=0.5). Since we are working with data located in an unstructured manner, the points on the line may fall between points from the original grid.

I, then, want to plot my varying coordinate vs my scalar (x-coordinate vs scalar in the above example).

I have been reading about interpolation tools provided in SciPy, but I cannot seem to find a way to do exactly what I have in mind.

I am looking for some direction in what tools/methods/approaches I can use/take to get this done.

Appreciate any help. Thank you.

I tried using LinearNDInterpolate and NearestNDInterpolate to interpolate the data onto a structured grid then extracting a subset from it, but my data is from an adaptive mesh that has been refined locally in areas of interest. A structured grid that encompasses the entire domain misses out on the finer details within these areas of interest.


Solution

  • You would need to have a surface in that respect and not just a single line.

    you can use scipy for the interpolation like this:

    from scipy.interpolate import griddata
    import pandas as pd
    
    import numpy as np
    
    def interpolate_z(df, x, y):
        # x, y, and z coordinates of the dataframe
        xi = df['x'].values
        yi = df['y'].values
        zi = df['z'].values
    
        # Interpolate the value of z
        result = griddata((xi, yi), zi, (x, y), rescale=True)
        return result
    

    You then have to create a surface to interpolate. Here is an example surface (meshgrid) that you could use:

    # dataframe containing a surface
    def surface_df():
        # Define the x and y coordinates of the surface
        x = np.linspace(-5, 5, 100)
        y = np.linspace(-5, 5, 100)
    
        # Create a grid of x and y coordinates
        X, Y = np.meshgrid(x, y)
    
        # Define the function of the surface
        Z = np.sin(np.sqrt(X**2 + Y**2))
    
        # Create a DataFrame from the grid and function
        df = pd.DataFrame({'x':X.ravel(), 'y':Y.ravel(), 'z':Z.ravel()})
    
        # Print the DataFrame
        print(df)
    
        return df
    

    ...and then the final part to test the code:

    df = surface_df()
    
    x = 2.5
    y = 1.5
    result = interpolate_z(df, x, y)
    print(result)
    

    with my example numbers and the example surface, i get this:

    0.22371169675502225