3

I’m working with a 3D dataset in Python where some (x,y) points create frame-like structures, some of them with multiple z-values per (x,y) pair, which seems to lead to a problem with griddata.

The provided code produces the interpolation between 2 data sets as a working example, and then tries to interpolate 2 data sets, where one has multiple z values. The data and the interpolation are plotted for each case. I also provide an image with a marking, what seems to create the problem afaik.

How can I interpolate such data with griddata or is there another way?

simulation data and corresponding 3D interpolation plot

Code contains part of the original (simulation) data.

import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import distance
from scipy.interpolate import griddata
from scipy.ndimage import gaussian_filter
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from matplotlib.colors import Normalize
from matplotlib import cm
import matplotlib.tri as mtri
from scipy.interpolate import LinearNDInterpolator


x1 = np.array([
    0, 0.08317108166803, 0.16393703317322, 0.24010197356808, 0.31189968667059,
    0.37964309047995, 0.44362962064596, 0.50416941327588, 0.56154833462750, 0.61603270573008,
    0.66785467575344, 0.71722870327800, 0.76434124363645, 0.80936126105512, 0.85243882934910,
    0.89371020366228, 0.93330023252176, 0.97132031393031, 1.0078733278234, 1.04305186588065,
    1.07694164659622, 1.10962198351184, 1.14116475234496, 1.17163490787683, 1.20109277181813,
    1.22959493653164, 1.25719327772516, 1.28393541084346, 1.30986533211137, 1.33502459428484,
    1.3594517119059, 1.38318253432743, 1.40625054167016, 1.428687092237, 1.45052182005806,
    1.47178239513572, 1.4924946731886, 1.51268282564772, 1.53236959683959, 1.55157657215197,
    1.5703240685486, 1.58863120287582, 1.60651600994447, 1.62399550071956, 1.64108576853907,
    1.65780207082065, 1.67415889980995, 1.69017008507776, 1.70584884180465, 1.72120783285127,
    1.73625905724844, 1.75101389043042, 1.76548311976239, 1.77967698639756, 1.79360519288652,
    1.80727689980216, 1.8207008202846, 1.83388518878035, 1.84683777315861, 1.85956584789141,
    1.87207616663999, 1.88437496210868, 1.89646789288332, 1.90835992552183, 1.92005539714572,
    1.9315578245162, 1.94286977773435, 1.95399269320514, 1.96492669014037, 1.97567031873621,
    1.98622026624029, 1.99657105652974, 2.00671480587649, 2.01664080378909, 2.02633512036696,
    2.03578034488985, 2.04495553215686, 2.05383630364206, 2.0623951776226, 2.0706018164916,
    2.07842481734728, 2.0858329876037, 2.09279775917234, 2.09929633971377, 2.10531538227125,
    2.11085508513429, 2.11593338459342, 2.12058937638755, 2.12488319044411, 2.12889284005344,
    2.13270923022591, 2.13642524129613
])


z1 = np.array([
    28.6619989743589, 28.6049608580482, 28.5450559014246, 28.4794835365082, 28.4092022241029,
    28.3350387336261, 28.2576380039013, 28.1775367384564, 28.0951654495223, 28.0108638015799,
    27.9249204615456, 27.8375597971889, 27.7489735572062, 27.6593178994861, 27.5687237423079,
    27.4773041964674, 27.385152945665, 27.2923533725037, 27.1989741902862, 27.1050785554844,
    27.0107190614389, 26.9159392616942, 26.8207798998579, 26.7252795524418, 26.6294706791138,
    26.5333790187747, 26.4370286448011, 26.3404423792824, 26.2436415876413, 26.1466433615791,
    26.0494627200553, 25.9521139974702, 25.8546109832136, 25.7569659319296, 25.6591888403289,
    25.5612891089313, 25.4632757574251, 25.3651575801692, 25.2669423848755, 25.168636129068,
    25.0702443614344, 24.9717723691753, 24.8732252294088, 24.7746078436806, 24.6759249761952,
    24.5771812831842, 24.4783811991822, 24.3795278208977, 24.2806239242195, 24.1816722476486,
    24.082675412506, 23.9836359405196, 23.8845562687947, 23.7854387639056, 23.6862857298263,
    23.5870993764416, 23.4878813512533, 23.3886330916743, 23.2893560024275, 23.1900514136945,
    23.0907205842034, 22.9913647072391, 22.8919849096176, 22.792582243255, 22.6931576855678,
    22.5937118769204, 22.4942453558146, 22.3947585791552, 22.2952518558259, 22.1957253129467,
    22.0961789025235, 21.9966124171542, 21.8970253898987, 21.7974170708687, 21.6977864181452,
    21.5981324310853, 21.4984538542985, 21.398749114135, 21.2990163991982, 21.1992542481573,
    21.0994617682189, 20.9996381351822, 20.8997827371874, 20.799896002592, 20.6999792732694,
    20.6000347502029, 20.5000657435458, 20.4000764848403, 20.3000713432661, 20.2000540343164,
    20.1000287433225, 20
])

y1 = np.full(len(x1),1)

x2 = np.array([
    0, 0.09970480868419, 0.19934990930324, 0.29892560671855, 0.39845053029212,
    0.49791294847979, 0.59729126792395, 0.69654894215390, 0.79562230931157,
    0.89441829468223, 0.99278184799703, 1.09041596346573, 1.18680564093363,
    1.2811247216627, 1.37173821384615, 1.45615592046124, 1.53140709459726,
    1.59481447147833, 1.64540118865725, 1.68420020117436, 1.7139567901805,
    1.73739377080012, 1.75669514508293, 1.77341533375185, 1.78855241978336,
    1.80270054725639, 1.81619925811863, 1.82923458834867, 1.84190868011591,
    1.8542787909028, 1.86637895717989, 1.87823123253782, 1.8898513429009,
    1.90125155489232, 1.91244211394041, 1.92343198232874, 1.93422925599876,
    1.94484137307261, 1.95527523060825, 1.96553726952681, 1.97563352932633,
    1.98556968830044, 1.99535109412568, 2.00498278811171, 2.01446952528177,
    2.02381579222306, 2.03302582656997, 2.04210365316528, 2.05105308938297,
    2.05987776623044, 2.06858114998522, 2.07716655334668, 2.08563714669058,
    2.09399597192344, 2.1022459544216, 2.11038991079032, 2.11843055346434,
    2.12637049464471, 2.13421224945851, 2.14195824744614, 2.14961083302462,
    2.15717226465044, 2.16464472287464, 2.17203031834828, 2.17933109740207,
    2.18654904729014, 2.19368610417827, 2.20074416242255, 2.20772507771543,
    2.21463066429355, 2.2214626950629, 2.22822290393084, 2.23491298448034,
    2.24153458547506, 2.24808930743357, 2.25457870003345, 2.26100425466765,
    2.26736739519304, 2.27366947406393, 2.27991176845626, 2.28609547194039,
    2.29222169050455, 2.29829141992375, 2.30430552303668, 2.31026470050494,
    2.31616945318094, 2.32202003758885, 2.32781640900641, 2.33355814983544,
    2.33924438051412, 2.3448736508916, 2.35044381228348, 2.3559518778997,
    2.36139385612463, 2.36676455738366, 2.37205741259143, 2.37726426201264,
    2.38237517331566, 2.38737831946074, 2.39225993069978, 2.39700436076639,
    2.40159431859356, 2.40601130725183, 2.41023630806784, 2.4142507588751,
    2.418037990112, 2.42158487083293, 2.42488372545427, 2.42793436504128,
    2.43074593332474, 2.4333379706335, 2.43574001568792, 2.4379889754186,
    2.44012113735539, 2.44214574160271
])

z2 = np.array([
    30.0078688964104, 30.0065512265173, 30.0029356360187, 29.9976735322442,
    29.9915262693748, 29.9844424862537, 29.9762659464609, 29.9667364364951,
    29.9554600427241, 29.9419800400481, 29.9256478232344, 29.9054159211507,
    29.8799561681087, 29.8476996253689, 29.8061730864421, 29.7532731986494,
    29.6880451094337, 29.6112448542866, 29.5253946922475, 29.4335819554567,
    29.3384411867613, 29.2415312959595, 29.1437049711797, 29.04539962879,
    28.9468401079325, 28.8481308935213, 28.7493306654707, 28.6504694225423,
    28.5515612207417, 28.4526148172972, 28.3536354145385, 28.2546261943038,
    28.1555895272291, 28.0565273761794, 27.9574414945533, 27.8583335076939,
    27.7592047062979, 27.6600561309973, 27.5608887508238, 27.4617034796921,
    27.3625011864055, 27.2632827022544, 27.1640488269094, 27.0648003331593,
    26.9655379708194, 26.866262470073, 26.7669745291472, 26.6676746328858,
    26.5683632230419, 26.4690407437848, 26.3697076224236, 26.2703642715209,
    26.171011090825, 26.0716484692661, 25.9722767866544, 25.8728964148864,
    25.7735077188227, 25.6741110570318, 25.5747068020388, 25.4752952472731,
    25.3758766209457, 25.2764511425401, 25.1770190239312, 25.077580470411,
    24.978135681488, 24.8786848515835, 24.7792281708969, 24.6797658262875,
    24.5802980016905, 24.4808248780774, 24.381346633632, 24.2818634440495,
    24.1823754825859, 24.0828829198801, 23.9833859238618, 23.8838846597107,
    23.7843792895138, 23.6848699718101, 23.5853568615186, 23.4858401098541,
    23.3863198605794, 23.2867961336504, 23.1872689742316, 23.0877384678003,
    22.9882046876333, 22.8886676931036, 22.7891275276662, 22.6895842161987,
    22.5900377616683, 22.4904881410033, 22.3909353002525, 22.2913791491932,
    22.1918194461756, 22.0922558825952, 21.9926883788735, 21.8931167722048,
    21.7935407990426, 21.6939600883707, 21.5943741599893, 21.4947824294466,
    21.395184222527, 21.2955788018895, 21.1959654064542, 21.0963434196656,
    20.9967131851386, 20.8970742537356, 20.7974262724062, 20.6977693400472,
    20.5981040167542, 20.4984312619284, 20.3987523065558, 20.2990684973495,
    20.1993811617366, 20.099691467103, 20
])

y2 = np.full(len(x2),2)

x3 = np.array([
    0, 0.106091997247487, 0.212282862868987, 0.318600341722176, 0.425123104761527,
    0.531901352872626, 0.638980673349671, 0.746408888895399, 0.85423835573243,
    0.962522013543275, 1.07131093710695, 1.18064439993891, 1.29054534660613,
    1.40102082494537, 1.51205952335725, 1.62363164712265, 1.73568405272677,
    1.84814589283292, 1.96093277164309, 2.07395098084042, 2.18706544796369,
    2.30006049798178, 2.41251892919309, 2.52351045392648, 2.63096976610101,
    2.73100121086301, 2.77148016441521, 2.78453458174498, 2.79186010794094,
    2.79751816975908, 2.80236248394865, 2.80670132496914, 2.81067659404222,
    2.81436810315714, 2.81782835677761, 2.81838473210957, 2.82109652791738,
    2.82420427153188, 2.82717868109766, 2.83004342751941, 2.83281945446213,
    2.83552519787279, 2.83817680575457, 2.84078819902162, 2.84337124785453,
    2.84593589783908, 2.84849035993836, 2.85104128587469, 2.85359396537556,
    2.85615250287907, 2.85872000627528, 2.86129873724824, 2.86389026304064,
    2.86649557135293, 2.86911518641933, 2.8717492484006, 2.87439759958004,
    2.87705983816952, 2.87973537526801, 2.88242347197052, 2.88512327706806,
    2.88783385231766, 2.88845703622116, 2.89055419723002, 2.89328326484414,
    2.89601997738632, 2.89876323695298, 2.90151193463858, 2.90426495815636,
    2.90702119863042, 2.90977955571619, 2.91253894330014, 2.91529829288703,
    2.91805655711182, 2.92081271230053, 2.92356576021251, 2.92631472933472,
    2.92905867580467, 2.93179668334584, 2.93452786251032, 2.93725134958514,
    2.93965292016822, 2.93996630533669, 2.94267191310587, 2.94536737736262,
    2.94805192150669, 2.95072478659992, 2.95338522921948, 2.9560325199586,
    2.95866594104728, 2.96128478419988, 2.96388834746919, 2.96647593163284,
    2.96904683568692, 2.97160035145282, 2.97413575724706, 2.97425125556441,
    2.97665231021929, 2.97914923756346, 2.98162572566976, 2.98408090824307,
    2.98651385151949, 2.98892353757412, 2.99130884415201, 2.99366851923393,
    2.99600114768388, 2.9962606601005, 2.99830510879971, 3.00057851901249,
    3.00281914620488, 3.00502428120326, 3.00719053828585, 3.00931351650196,
    3.00952011645174, 3.01138721018009, 3.0134029388599, 3.01534737564675,
    3.01699921085196, 3.01719889804888, 3.01892089400833, 3.02044973125651,
    3.02078939388317, 3.02167377283328, 3.02228920892799, 3.02239824880744
])

z3 = np.array([
    30.1186241174416, 30.1184849219899, 30.1171034471136, 30.1152951272103, 30.1133655615441,
    30.1113195993005, 30.1091433108655, 30.1068210776114, 30.1043270725803, 30.1016326866963,
    30.0986949871154, 30.095463219881, 30.091866695563, 30.087823561571, 30.0832240264785,
    30.0779411584852, 30.0718042824719, 30.064598064254, 30.0560271138372, 30.0456642379577,
    30.0328664792409, 30.0166381634173, 29.995383512023, 29.9666311419869, 29.9269062544625,
    29.8724446142301, 20, 20.0992866487574, 20.1987778658839, 20.2983155533319, 20.3978803414887,
    20.4974615256815, 20.5970538814448, 20.6966543922422, 20.796260963899, 29.8010645620936,
    20.8958720196992, 20.9954865830927, 21.0951039613303, 21.1947236485541, 21.2943452750121,
    21.3939685837807, 21.493593496968, 21.5932201164118, 21.6928485704969, 21.7924790313127,
    21.8921116969745, 21.9917467869875, 22.0913845424964, 22.1910252330904, 22.2906691240923,
    22.3903164843267, 22.4899675841224, 22.5896226941457, 22.6892820856006, 22.7889460266206,
    22.888614783746, 22.988288620861, 23.0879678014928, 23.1876525873797, 23.287343240002,
    23.3870400197103, 29.7142868959217, 23.486743187404, 23.5864530033367, 23.6861697290352,
    23.7858936263979, 23.885624958565, 23.9853639878029, 24.0851109788725, 24.1848661985415,
    24.2846299172733, 24.3844024085183, 24.4841839497909, 24.5839748236319, 24.6837753181654,
    24.7835857287758, 24.8834063591202, 24.9832375223667, 25.0830795430067, 25.1829327578276,
    29.6171448515155, 25.2827975190689, 25.3826741941813, 25.4825631716602, 25.5824648589361,
    25.6823796912861, 25.7823081276471, 25.8822506637417, 25.9822078278468, 26.0821801933113,
    26.1821683788585, 26.2821730607998, 26.3821949758609, 26.482234934283, 26.5822938276285,
    29.5148759694037, 26.6823726493158, 26.7824724970099, 26.8825946040959, 26.9827403478161,
    27.0829112850487, 27.1831091758242, 27.283336026885, 27.3835941282532, 27.4838861281617,
    29.4108704451581, 27.5842150845333, 27.6845846449453, 27.7849990464475, 27.8854632367103,
    27.9859831360428, 28.0865659498792, 29.3067361736195, 28.1872205245328, 28.2879579643369,
    28.3887923780716, 29.2030641097122, 28.4897421297855, 28.5908314496745, 28.6920929845482,
    29.0999759013086, 28.7935707828626, 28.997430828688, 28.8953250739844
])

y3 = np.full(len(x3),3)

def filter_data_by_indices(data, indices_to_keep):
 
    # Convert 1-based indices to 0-based indices for Python indexing
    indices_to_keep = [i - 1 for i in indices_to_keep]
    
    # Filter the data by the specified indices
    filtered_data = [data[i] for i in indices_to_keep if 0 <= i < len(data)]
    return filtered_data


def mirror_data(data):
    mirrored_data = []
    for x,y,z in data:
        
        # Combine positive and negative r values
        x_combined = np.concatenate([-x[::-1], x])
        z_combined = np.concatenate( [z[::-1], z ])-20 #offset of sim raw data
        y_combined = np.full_like(x_combined, y[0])
        mirrored_data.append((x_combined, y_combined, z_combined))
    return mirrored_data


def nearest_neighbor_sort(data):
    sorted_data = []
    for x, y, z in data:
        # Stack x and z to form (x, z) pairs
        xz_pairs = np.column_stack((x, z))

        # Nearest neighbor sorting
        sorted_indices = [0]  # Start with the first point
        remaining_indices = list(range(1, len(xz_pairs)))

        while remaining_indices:
            last_index = sorted_indices[-1]
            distances = [
                distance.euclidean(xz_pairs[last_index], xz_pairs[i]) for i in remaining_indices
            ]
            nearest_index = remaining_indices[np.argmin(distances)]
            sorted_indices.append(nearest_index)
            remaining_indices.remove(nearest_index)

        # Apply the sorted indices to x and z, y remains unchanged
        x_sorted = x[sorted_indices]
        z_sorted = z[sorted_indices]
        sorted_data.append((x_sorted, y, z_sorted))
    return sorted_data


def plot_data(filtered_data):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    all_x, all_y, all_z = [], [], []

    for x, y, z in filtered_data:
        # log_t = np.log10(t)
        
        all_x.extend(x)
        all_y.extend(y)
        all_z.extend(z)

        ax.plot(x, y, z, color='black', alpha=0.8, linewidth=1.5)
       
    plt.show()
    
    # Interpolate surface
    X, Y, Z = interpolate_surface(all_x, all_y, all_z)

    X_flat, Y_flat, Z_flat = X.flatten(), Y.flatten(), Z.flatten()
    triangles = mtri.Triangulation(X_flat, Y_flat)

    norm = Normalize(vmin=min(Y_flat), vmax=max(Y_flat))
    cmap = cm.gnuplot
    colors = cmap(norm(Y_flat))

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    # Build Poly3DCollection
    poly3d = []
    for tri in triangles.triangles:
        poly3d.append([(X_flat[tri[0]], Y_flat[tri[0]], Z_flat[tri[0]]),
                       (X_flat[tri[1]], Y_flat[tri[1]], Z_flat[tri[1]]),
                       (X_flat[tri[2]], Y_flat[tri[2]], Z_flat[tri[2]])])

    poly_collection = Poly3DCollection(poly3d, facecolors=colors[triangles.triangles].mean(axis=1),
                                        edgecolors='black', linewidths=0.06, alpha=1)
    ax.add_collection3d(poly_collection)

    plt.show()


def interpolate_surface(all_r, all_log_t, all_z, num_points=100, sigma=1):
  
  
    r_vals = np.linspace(min(all_r), max(all_r), num_points)
    t_vals = np.linspace(min(all_log_t), max(all_log_t), num_points)
    R, T = np.meshgrid(r_vals, t_vals)

    points = np.vstack((all_r, all_log_t)).T
    values = np.array(all_z)
    Z = griddata(points, values, (R, T), method='linear') # 'cubic' or 'nearest'
      
    ## Interpolate the data with linearNDInterpolator 
    # interpolator = LinearNDInterpolator(points, values)
    # Z = interpolator(np.array([R.flatten(), T.flatten()]).T).reshape(R.shape)
    
    Z = np.nan_to_num(Z, nan=0)
    # Z = gaussian_filter(Z, sigma=sigma)
    return R, T, Z


data = [(x1,y1,z1),(x2,y2,z2),(x3,y3,z3)]


# plot first 2 data sets
filtered_data = filter_data_by_indices(data, [1,2])

sorted_data = nearest_neighbor_sort(filtered_data)

mirrored_data = mirror_data(sorted_data)

plot_data(mirrored_data)

# plot last 2 data sets (here interpolation is wrong)

filtered_data = filter_data_by_indices(data, [2,3])

sorted_data = nearest_neighbor_sort(filtered_data)

mirrored_data = mirror_data(sorted_data)

plot_data(mirrored_data)

1 Answer 1

6

Don't interpolate in a rectilinear parameter space. Instead, you need to

  1. Transform to a semipolar (cylindrical) coordinate space with y as linear, and xz radius and xz angle as the other axes. If I had to guess a safe x-z origin, it would be (0, 0).
  2. Interpolate on that.
  3. Prior to graphing, transform back to xyz.

This is the safest "dumb" solution that will fit your data. If your data have a different hidden parameter space that produce unique, somewhat uniform dependent coordinates then you should use that instead.

I also don't understand you're making your own triangle mesh. It causes problems even with a well-parameterized dataset. Just use plot_surface instead:

import typing

import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import scipy
from scipy.spatial.distance import euclidean
from mpl_toolkits.mplot3d.art3d import Poly3DCollection


def mirror_data(
    data: list[tuple[np.ndarray, np.ndarray, np.ndarray]],
) -> list[np.ndarray]:
    mirrored_data = []
    for x, y, z in data:
        # Combine positive and negative r values
        x_combined = np.concatenate([-x[::-1], x])
        z_combined = np.concatenate([z[::-1], z]) - 20  # offset of sim raw data
        y_combined = np.full_like(x_combined, y[0])
        mirrored_data.append(np.array((x_combined, y_combined, z_combined)))
    return mirrored_data


def nearest_neighbor_sort(data: typing.Sequence[np.ndarray]) -> list[np.ndarray]:
    sorted_data = []
    for x, y, z in data:
        # Stack x and z to form (x, z) pairs
        xz_pairs = np.column_stack((x, z))

        # Nearest neighbor sorting
        sorted_indices = [0]  # Start with the first point
        remaining_indices = list(range(1, len(xz_pairs)))

        while remaining_indices:
            last_index = sorted_indices[-1]
            distances = [
                euclidean(xz_pairs[last_index], xz_pairs[i]) for i in remaining_indices
            ]
            nearest_index = remaining_indices[np.argmin(distances)]
            sorted_indices.append(nearest_index)
            remaining_indices.remove(nearest_index)

        # Apply the sorted indices to x and z, y remains unchanged
        x_sorted = x[sorted_indices]
        z_sorted = z[sorted_indices]
        sorted_data.append(np.array((x_sorted, y, z_sorted)))
    return sorted_data


def plot_data(filtered_data: list[np.ndarray]) -> None:
    fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
    ax.set_xlabel('R')
    ax.set_ylabel('T')
    ax.set_zlabel('Z')
    all_x, all_y, all_z = np.concatenate(filtered_data, axis=-1)

    for x, y, z in filtered_data:
        # log_t = np.log10(t)
        ax.plot(x, y, z, color='black', alpha=0.8, linewidth=1.5)

    # Interpolate surface
    X, Y, Z = interpolate_surface(all_x, all_y, all_z, num_points=50)

    fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
    ax.set_xlabel('R')
    ax.set_ylabel('T')
    ax.set_zlabel('Z')
    ax.plot_surface(X, Y, Z, cmap=matplotlib.cm.plasma)


def interpolate_surface(
    all_r: np.ndarray,
    all_log_t: np.ndarray,
    all_z: np.ndarray,
    num_points: int = 100,
    sigma: float = 1.,
    gaussian: bool = False,
) -> tuple[
    np.ndarray,  # R
    np.ndarray,  # T
    np.ndarray,  # Z
]:
    # r_vals = np.linspace(all_r.min(), all_r.max(), num_points)
    t_vals = np.linspace(all_log_t.min(), all_log_t.max(), num_points)
    phi_vals = np.linspace(0, np.pi, num_points)
    P, T = np.meshgrid(phi_vals, t_vals)

    # t is kept as linear. Transform r,z to a cylindrical system.
    rmax = np.abs(all_r).max()
    zmax = np.abs(all_z).max()
    rscale = all_r/rmax
    zscale = all_z/zmax
    radius = np.hypot(zscale, rscale)
    angle = np.atan2(zscale, rscale)

    points = np.stack((angle, all_log_t), axis=-1)
    grid_radius = scipy.interpolate.griddata(points, radius, (P, T), method='linear')  # 'cubic' or 'nearest'
    if gaussian:
        grid_radius = scipy.ndimage.gaussian_filter(grid_radius, sigma=sigma)

    # Transform from cylindrical angle (P), T, grid_radius to R, T, Z
    R = rmax * grid_radius * np.cos(P)
    Z = zmax * grid_radius * np.sin(P)

    return R, T, Z


def demo() -> None:
    x1 = np.array((
        0, 0.08317108166803, 0.16393703317322, 0.24010197356808, 0.31189968667059,
        0.37964309047995, 0.44362962064596, 0.50416941327588, 0.56154833462750, 0.61603270573008,
        0.66785467575344, 0.71722870327800, 0.76434124363645, 0.80936126105512, 0.85243882934910,
        0.89371020366228, 0.93330023252176, 0.97132031393031, 1.0078733278234, 1.04305186588065,
        1.07694164659622, 1.10962198351184, 1.14116475234496, 1.17163490787683, 1.20109277181813,
        1.22959493653164, 1.25719327772516, 1.28393541084346, 1.30986533211137, 1.33502459428484,
        1.3594517119059, 1.38318253432743, 1.40625054167016, 1.428687092237, 1.45052182005806,
        1.47178239513572, 1.4924946731886, 1.51268282564772, 1.53236959683959, 1.55157657215197,
        1.5703240685486, 1.58863120287582, 1.60651600994447, 1.62399550071956, 1.64108576853907,
        1.65780207082065, 1.67415889980995, 1.69017008507776, 1.70584884180465, 1.72120783285127,
        1.73625905724844, 1.75101389043042, 1.76548311976239, 1.77967698639756, 1.79360519288652,
        1.80727689980216, 1.8207008202846, 1.83388518878035, 1.84683777315861, 1.85956584789141,
        1.87207616663999, 1.88437496210868, 1.89646789288332, 1.90835992552183, 1.92005539714572,
        1.9315578245162, 1.94286977773435, 1.95399269320514, 1.96492669014037, 1.97567031873621,
        1.98622026624029, 1.99657105652974, 2.00671480587649, 2.01664080378909, 2.02633512036696,
        2.03578034488985, 2.04495553215686, 2.05383630364206, 2.0623951776226, 2.0706018164916,
        2.07842481734728, 2.0858329876037, 2.09279775917234, 2.09929633971377, 2.10531538227125,
        2.11085508513429, 2.11593338459342, 2.12058937638755, 2.12488319044411, 2.12889284005344,
        2.13270923022591, 2.13642524129613
    ))

    z1 = np.array((
        28.6619989743589, 28.6049608580482, 28.5450559014246, 28.4794835365082, 28.4092022241029,
        28.3350387336261, 28.2576380039013, 28.1775367384564, 28.0951654495223, 28.0108638015799,
        27.9249204615456, 27.8375597971889, 27.7489735572062, 27.6593178994861, 27.5687237423079,
        27.4773041964674, 27.385152945665, 27.2923533725037, 27.1989741902862, 27.1050785554844,
        27.0107190614389, 26.9159392616942, 26.8207798998579, 26.7252795524418, 26.6294706791138,
        26.5333790187747, 26.4370286448011, 26.3404423792824, 26.2436415876413, 26.1466433615791,
        26.0494627200553, 25.9521139974702, 25.8546109832136, 25.7569659319296, 25.6591888403289,
        25.5612891089313, 25.4632757574251, 25.3651575801692, 25.2669423848755, 25.168636129068,
        25.0702443614344, 24.9717723691753, 24.8732252294088, 24.7746078436806, 24.6759249761952,
        24.5771812831842, 24.4783811991822, 24.3795278208977, 24.2806239242195, 24.1816722476486,
        24.082675412506, 23.9836359405196, 23.8845562687947, 23.7854387639056, 23.6862857298263,
        23.5870993764416, 23.4878813512533, 23.3886330916743, 23.2893560024275, 23.1900514136945,
        23.0907205842034, 22.9913647072391, 22.8919849096176, 22.792582243255, 22.6931576855678,
        22.5937118769204, 22.4942453558146, 22.3947585791552, 22.2952518558259, 22.1957253129467,
        22.0961789025235, 21.9966124171542, 21.8970253898987, 21.7974170708687, 21.6977864181452,
        21.5981324310853, 21.4984538542985, 21.398749114135, 21.2990163991982, 21.1992542481573,
        21.0994617682189, 20.9996381351822, 20.8997827371874, 20.799896002592, 20.6999792732694,
        20.6000347502029, 20.5000657435458, 20.4000764848403, 20.3000713432661, 20.2000540343164,
        20.1000287433225, 20
    ))

    x2 = np.array((
        0, 0.09970480868419, 0.19934990930324, 0.29892560671855, 0.39845053029212,
        0.49791294847979, 0.59729126792395, 0.69654894215390, 0.79562230931157,
        0.89441829468223, 0.99278184799703, 1.09041596346573, 1.18680564093363,
        1.2811247216627, 1.37173821384615, 1.45615592046124, 1.53140709459726,
        1.59481447147833, 1.64540118865725, 1.68420020117436, 1.7139567901805,
        1.73739377080012, 1.75669514508293, 1.77341533375185, 1.78855241978336,
        1.80270054725639, 1.81619925811863, 1.82923458834867, 1.84190868011591,
        1.8542787909028, 1.86637895717989, 1.87823123253782, 1.8898513429009,
        1.90125155489232, 1.91244211394041, 1.92343198232874, 1.93422925599876,
        1.94484137307261, 1.95527523060825, 1.96553726952681, 1.97563352932633,
        1.98556968830044, 1.99535109412568, 2.00498278811171, 2.01446952528177,
        2.02381579222306, 2.03302582656997, 2.04210365316528, 2.05105308938297,
        2.05987776623044, 2.06858114998522, 2.07716655334668, 2.08563714669058,
        2.09399597192344, 2.1022459544216, 2.11038991079032, 2.11843055346434,
        2.12637049464471, 2.13421224945851, 2.14195824744614, 2.14961083302462,
        2.15717226465044, 2.16464472287464, 2.17203031834828, 2.17933109740207,
        2.18654904729014, 2.19368610417827, 2.20074416242255, 2.20772507771543,
        2.21463066429355, 2.2214626950629, 2.22822290393084, 2.23491298448034,
        2.24153458547506, 2.24808930743357, 2.25457870003345, 2.26100425466765,
        2.26736739519304, 2.27366947406393, 2.27991176845626, 2.28609547194039,
        2.29222169050455, 2.29829141992375, 2.30430552303668, 2.31026470050494,
        2.31616945318094, 2.32202003758885, 2.32781640900641, 2.33355814983544,
        2.33924438051412, 2.3448736508916, 2.35044381228348, 2.3559518778997,
        2.36139385612463, 2.36676455738366, 2.37205741259143, 2.37726426201264,
        2.38237517331566, 2.38737831946074, 2.39225993069978, 2.39700436076639,
        2.40159431859356, 2.40601130725183, 2.41023630806784, 2.4142507588751,
        2.418037990112, 2.42158487083293, 2.42488372545427, 2.42793436504128,
        2.43074593332474, 2.4333379706335, 2.43574001568792, 2.4379889754186,
        2.44012113735539, 2.44214574160271
    ))

    z2 = np.array((
        30.0078688964104, 30.0065512265173, 30.0029356360187, 29.9976735322442,
        29.9915262693748, 29.9844424862537, 29.9762659464609, 29.9667364364951,
        29.9554600427241, 29.9419800400481, 29.9256478232344, 29.9054159211507,
        29.8799561681087, 29.8476996253689, 29.8061730864421, 29.7532731986494,
        29.6880451094337, 29.6112448542866, 29.5253946922475, 29.4335819554567,
        29.3384411867613, 29.2415312959595, 29.1437049711797, 29.04539962879,
        28.9468401079325, 28.8481308935213, 28.7493306654707, 28.6504694225423,
        28.5515612207417, 28.4526148172972, 28.3536354145385, 28.2546261943038,
        28.1555895272291, 28.0565273761794, 27.9574414945533, 27.8583335076939,
        27.7592047062979, 27.6600561309973, 27.5608887508238, 27.4617034796921,
        27.3625011864055, 27.2632827022544, 27.1640488269094, 27.0648003331593,
        26.9655379708194, 26.866262470073, 26.7669745291472, 26.6676746328858,
        26.5683632230419, 26.4690407437848, 26.3697076224236, 26.2703642715209,
        26.171011090825, 26.0716484692661, 25.9722767866544, 25.8728964148864,
        25.7735077188227, 25.6741110570318, 25.5747068020388, 25.4752952472731,
        25.3758766209457, 25.2764511425401, 25.1770190239312, 25.077580470411,
        24.978135681488, 24.8786848515835, 24.7792281708969, 24.6797658262875,
        24.5802980016905, 24.4808248780774, 24.381346633632, 24.2818634440495,
        24.1823754825859, 24.0828829198801, 23.9833859238618, 23.8838846597107,
        23.7843792895138, 23.6848699718101, 23.5853568615186, 23.4858401098541,
        23.3863198605794, 23.2867961336504, 23.1872689742316, 23.0877384678003,
        22.9882046876333, 22.8886676931036, 22.7891275276662, 22.6895842161987,
        22.5900377616683, 22.4904881410033, 22.3909353002525, 22.2913791491932,
        22.1918194461756, 22.0922558825952, 21.9926883788735, 21.8931167722048,
        21.7935407990426, 21.6939600883707, 21.5943741599893, 21.4947824294466,
        21.395184222527, 21.2955788018895, 21.1959654064542, 21.0963434196656,
        20.9967131851386, 20.8970742537356, 20.7974262724062, 20.6977693400472,
        20.5981040167542, 20.4984312619284, 20.3987523065558, 20.2990684973495,
        20.1993811617366, 20.099691467103, 20
    ))

    x3 = np.array((
        0, 0.106091997247487, 0.212282862868987, 0.318600341722176, 0.425123104761527,
        0.531901352872626, 0.638980673349671, 0.746408888895399, 0.85423835573243,
        0.962522013543275, 1.07131093710695, 1.18064439993891, 1.29054534660613,
        1.40102082494537, 1.51205952335725, 1.62363164712265, 1.73568405272677,
        1.84814589283292, 1.96093277164309, 2.07395098084042, 2.18706544796369,
        2.30006049798178, 2.41251892919309, 2.52351045392648, 2.63096976610101,
        2.73100121086301, 2.77148016441521, 2.78453458174498, 2.79186010794094,
        2.79751816975908, 2.80236248394865, 2.80670132496914, 2.81067659404222,
        2.81436810315714, 2.81782835677761, 2.81838473210957, 2.82109652791738,
        2.82420427153188, 2.82717868109766, 2.83004342751941, 2.83281945446213,
        2.83552519787279, 2.83817680575457, 2.84078819902162, 2.84337124785453,
        2.84593589783908, 2.84849035993836, 2.85104128587469, 2.85359396537556,
        2.85615250287907, 2.85872000627528, 2.86129873724824, 2.86389026304064,
        2.86649557135293, 2.86911518641933, 2.8717492484006, 2.87439759958004,
        2.87705983816952, 2.87973537526801, 2.88242347197052, 2.88512327706806,
        2.88783385231766, 2.88845703622116, 2.89055419723002, 2.89328326484414,
        2.89601997738632, 2.89876323695298, 2.90151193463858, 2.90426495815636,
        2.90702119863042, 2.90977955571619, 2.91253894330014, 2.91529829288703,
        2.91805655711182, 2.92081271230053, 2.92356576021251, 2.92631472933472,
        2.92905867580467, 2.93179668334584, 2.93452786251032, 2.93725134958514,
        2.93965292016822, 2.93996630533669, 2.94267191310587, 2.94536737736262,
        2.94805192150669, 2.95072478659992, 2.95338522921948, 2.9560325199586,
        2.95866594104728, 2.96128478419988, 2.96388834746919, 2.96647593163284,
        2.96904683568692, 2.97160035145282, 2.97413575724706, 2.97425125556441,
        2.97665231021929, 2.97914923756346, 2.98162572566976, 2.98408090824307,
        2.98651385151949, 2.98892353757412, 2.99130884415201, 2.99366851923393,
        2.99600114768388, 2.9962606601005, 2.99830510879971, 3.00057851901249,
        3.00281914620488, 3.00502428120326, 3.00719053828585, 3.00931351650196,
        3.00952011645174, 3.01138721018009, 3.0134029388599, 3.01534737564675,
        3.01699921085196, 3.01719889804888, 3.01892089400833, 3.02044973125651,
        3.02078939388317, 3.02167377283328, 3.02228920892799, 3.02239824880744
    ))

    z3 = np.array((
        30.1186241174416, 30.1184849219899, 30.1171034471136, 30.1152951272103, 30.1133655615441,
        30.1113195993005, 30.1091433108655, 30.1068210776114, 30.1043270725803, 30.1016326866963,
        30.0986949871154, 30.095463219881, 30.091866695563, 30.087823561571, 30.0832240264785,
        30.0779411584852, 30.0718042824719, 30.064598064254, 30.0560271138372, 30.0456642379577,
        30.0328664792409, 30.0166381634173, 29.995383512023, 29.9666311419869, 29.9269062544625,
        29.8724446142301, 20, 20.0992866487574, 20.1987778658839, 20.2983155533319,
        20.3978803414887,
        20.4974615256815, 20.5970538814448, 20.6966543922422, 20.796260963899, 29.8010645620936,
        20.8958720196992, 20.9954865830927, 21.0951039613303, 21.1947236485541, 21.2943452750121,
        21.3939685837807, 21.493593496968, 21.5932201164118, 21.6928485704969, 21.7924790313127,
        21.8921116969745, 21.9917467869875, 22.0913845424964, 22.1910252330904, 22.2906691240923,
        22.3903164843267, 22.4899675841224, 22.5896226941457, 22.6892820856006, 22.7889460266206,
        22.888614783746, 22.988288620861, 23.0879678014928, 23.1876525873797, 23.287343240002,
        23.3870400197103, 29.7142868959217, 23.486743187404, 23.5864530033367, 23.6861697290352,
        23.7858936263979, 23.885624958565, 23.9853639878029, 24.0851109788725, 24.1848661985415,
        24.2846299172733, 24.3844024085183, 24.4841839497909, 24.5839748236319, 24.6837753181654,
        24.7835857287758, 24.8834063591202, 24.9832375223667, 25.0830795430067, 25.1829327578276,
        29.6171448515155, 25.2827975190689, 25.3826741941813, 25.4825631716602, 25.5824648589361,
        25.6823796912861, 25.7823081276471, 25.8822506637417, 25.9822078278468, 26.0821801933113,
        26.1821683788585, 26.2821730607998, 26.3821949758609, 26.482234934283, 26.5822938276285,
        29.5148759694037, 26.6823726493158, 26.7824724970099, 26.8825946040959, 26.9827403478161,
        27.0829112850487, 27.1831091758242, 27.283336026885, 27.3835941282532, 27.4838861281617,
        29.4108704451581, 27.5842150845333, 27.6845846449453, 27.7849990464475, 27.8854632367103,
        27.9859831360428, 28.0865659498792, 29.3067361736195, 28.1872205245328, 28.2879579643369,
        28.3887923780716, 29.2030641097122, 28.4897421297855, 28.5908314496745, 28.6920929845482,
        29.0999759013086, 28.7935707828626, 28.997430828688, 28.8953250739844
    ))

    y1 = np.full_like(x1, 1)
    y2 = np.full_like(x2, 2)
    y3 = np.full_like(x3, 3)

    data = (
        np.array((x1, y1, z1)), np.array((x2, y2, z2)), np.array((x3, y3, z3)),
    )

    # plot first 2 data sets
    sorted_data = nearest_neighbor_sort(data[:2])
    mirrored_data = mirror_data(sorted_data)
    plot_data(mirrored_data)

    # plot last 2 data sets (here interpolation is wrong)
    sorted_data = nearest_neighbor_sort(data[1:])
    mirrored_data = mirror_data(sorted_data)
    plot_data(mirrored_data)

    plt.show()


if __name__ == '__main__':
    demo()

plot

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. This helps a lot and is actually quite logic :O Hope this might help other people, too. :) And also thx for the slight changes in the code, I will carefully review them and learn more about python.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.