[Python] Create points grid on irregular (non-rectangular) planar surface

Discussão em 'Python' iniciado por Stack, Março 13, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using Python to plot 2D data, exported from a CFD software. The data is recorded in the CFD software at the mesh centroids, but I would like to plot it on a point grid with regular point spacing. This could be done using the scipy.interpolate.griddata function, but I have no idea how to generate the regular spacing point grid on non-rectangular planar surface.

    I suppose I could break up this non-rectangular surface into very small rectangles, but I was wondering if there is already a function that does this.

    Update: I tried following Christian Karcher's advice from the comment bellow, I created a rectangular grid with uniform distance between points and tried to interpolate the exported data onto the grid and displaying it, but I get kinda weird results. The linear interpolation method doesn't exclude all the points without any values.

    I added the code bellow and also attached the image of the plot (actual data, grid, linear interpol).

    # Read data

    input_filename = 'period_rot_shadow_vel-mag_p-stat.txt'

    df_results = pd.read_csv(input_filename, sep =',', skiprows = 1, names = ['nodenumber', 'X', 'Y', 'Z',
    'p_stat', 'vel_magnitude'])


    #---------------------- CREATE RECTANGULAR GRID ----------------

    # Rectangular grid is created with a numpy.meshgrid function, which takes 2 1D arrays to define the
    #size of the rectangular grid and the spacing between the points

    #get the size of the data to generate the same size array
    x_data_min = df_results['X'].min()
    x_data_max = df_results['X'].max()
    y_data_min = df_results['Y'].min()
    y_data_max = df_results['Y'].max()

    print(x_data_min)
    print(x_data_max)
    print(y_data_min)
    print(y_data_max)

    #from max and min values calculate the range (size) for both axis
    x_size = np.abs(x_data_max) + np.abs(x_data_min)
    y_size = np.abs(y_data_max) + np.abs(y_data_min)

    print(x_size)
    print(y_size)

    #create 2 numpy arrays to define the size and the spacing of the rectangular grid, arrays
    #are defined as lists, so we can use the list comprehension to use the data size parameters and the
    #desired spacing
    #all values are in meters

    rect_mesh_spacing = 0.001

    #number of points on each edge is calculated from the x_size and spacing, +1 is added so that we always
    #cover the whole area covered in exported data
    N_x_steps = int(x_size/rect_mesh_spacing) + 1
    N_y_steps = int(y_size/rect_mesh_spacing) + 1

    #create an empty list to fill with the values
    rect_mesh_x_axis = np.array([])
    rect_mesh_y_axis = np.array([])

    #for loop to fill the list of evenly spaced value in the x axis
    for i in range(0, N_x_steps):
    x = x_data_min + i * rect_mesh_spacing
    print(x)
    rect_mesh_x_axis = np.append(rect_mesh_x_axis, x)

    for i in range(0, N_y_steps):
    y = y_data_min + i * rect_mesh_spacing
    print(y)
    rect_mesh_y_axis = np.append(rect_mesh_y_axis, y)

    print(rect_mesh_x_axis)
    print(rect_mesh_y_axis)

    #use meshgrid function to create a rectangular grid
    xx, yy = np.meshgrid(rect_mesh_x_axis, rect_mesh_y_axis)





    #-------------------- INTERPOLATE DATA TO RECTANGULAR GRID ----------

    # scipy.interpolate.griddata(points, values, xi)
    #points = data point coordinates of the values we want to interpolate
    #values = the values at the points
    #xi = points at which to interpolate data
    interpolated_data_nearest = scipy.interpolate.griddata((df_results['X'], df_results['Y']), df_results['p_stat'],
    (xx, yy), method = 'nearest')
    interpolated_data_linear = scipy.interpolate.griddata((df_results['X'], df_results['Y']), df_results['p_stat'],
    (xx, yy), method = 'linear')
    interpolated_data_cubic = scipy.interpolate.griddata((df_results['X'], df_results['Y']), df_results['p_stat'],
    (xx, yy), method = 'cubic')

    #------------------------- PLOT ---------------------------------
    fig, axs = plt.subplots(1,5)
    fig.set_size_inches(13, 4)

    # Plot non-interpolated data
    z = df_results['p_stat']
    axs[0].scatter(df_results['X'], df_results['Y'], c = z,
    norm = matplotlib.colors.Normalize(vmin = np.min(z), vmax = np.max(z)), cmap = 'bwr', s=2)


    # Plot rectangular uniform empty grid
    axs[1].plot(xx, yy, marker='.', color = 'k', linestyle='none')

    # Plot interpolated data
    z1 = interpolated_data_nearest
    z2 = interpolated_data_linear
    z3 = interpolated_data_cubic

    axs[2].scatter(xx, yy, c = z1, norm = matplotlib.colors.Normalize(vmin = np.min(z1), vmax = np.max(z1)),
    cmap = 'bwr', s=2)
    axs[3].scatter(xx, yy, c = z2, norm = matplotlib.colors.Normalize(vmin = np.min(z2), vmax = np.max(z2)),
    cmap = 'bwr', s=2)
    axs[4].scatter(xx, yy, c = z3, norm = matplotlib.colors.Normalize(vmin = np.min(z3), vmax = np.max(z3)),
    cmap = 'bwr', s=2)



    plt.show()


    [​IMG]

    Continue reading...

Compartilhe esta Página