Как преобразовать диаграмму рассеяния в контурную? - PullRequest
0 голосов
/ 27 мая 2020

Я хотел бы преобразовать диаграмму рассеяния в контурную диаграмму. Как мне go сделать это с имеющимися у меня данными? Вот код:

import numpy as np
import matplotlib.pyplot as plt
x = np.array([-75.55846, -75.5459 , -75.56686, -75.55276, -75.57951, -75.58955,
   -75.59967, -75.53964, -75.65485, -75.55292, -75.59622, -75.57392,
   -75.47077, -75.58644, -75.68264, -75.56732, -75.59502, -75.37198,
   -75.59585, -75.57081, -75.40989, -75.50928, -75.54841, -75.72734,
   -75.36676, -75.79303, -75.36966, -75.69282, -75.42498, -75.57986,
   -75.58644, -75.64551, -75.45509, -75.47098])
y = np.array([38.07759, 38.07541, 38.06712, 38.09973, 38.06692, 38.09264,
   38.08731, 38.0822 , 38.36981, 38.06027, 38.07962, 38.08531,
   37.93448, 38.07716, 37.71758, 38.08925, 38.0975 , 38.33174,
   38.05731, 38.05515, 38.0547 , 38.1398 , 38.066  , 38.27009,
   37.93415, 38.24889, 38.19691, 38.03272, 38.19954, 37.91286,
   37.97847, 38.29755, 38.01239, 37.93453])
z = np.array([17.526, 21.336, 19.558, 17.78 , 20.828, 20.828, 20.066, 21.082,
   18.542, 20.32 , 19.812, 19.05 , 16.51 , 20.066, 25.654, 16.51 ,
   18.542, 17.018, 20.828, 21.844, 21.59 , 16.764, 20.828, 19.558,
   19.812, 22.606, 25.146, 19.558, 20.574, 24.13 , 35.306, 19.558,
   23.876, 18.796])
fig, ax = plt.subplots(figsize=(8,8))
ax.scatter(x, y, c=z)
plt.show()

scatter plot

Ответы [ 2 ]

0 голосов
/ 28 мая 2020

Думаю, я нашел решение - см. Ниже. В основном x, y и z - это одномерные массивы, а X, Y и Z - двумерные массивы, которые принимает контур, и он работает. Я скажу, что я осмотрелся, чтобы понять это ... так что это не было моей собственной.

def grid(x, y, z, resX=100, resY=100):
    #prepare to create grid
    xi = np.linspace(min(x), max(x), resX)
    yi = np.linspace(min(y), max(y), resY)

    #grid x, y, z
    X, Y = np.meshgrid(xi, yi)
    Z = griddata((x, y), z, (X, Y), method='linear')
    return X, Y, Z
0 голосов
/ 27 мая 2020

Это не обязательно лучший способ, но одним из способов сделать это может быть преобразование данных в z-значение для каждой точки в сетке x, y. Это можно сделать разными способами с разными результатами, но я выбрал способ использовать средневзвешенное значение z на основе расстояния до каждой точки. falloff можно отрегулировать, чтобы изменить степень изменения влияния точки по мере удаления от этой точки (оставьте положительное значение). Также можно использовать

import numpy as np
import matplotlib.pyplot as plt

x_arr = np.array([-75.55846, -75.5459, -75.56686, -75.55276, -75.57951, -75.58955,
                  -75.59967, -75.53964, -75.65485, -75.55292, -75.59622, -75.57392,
                  -75.47077, -75.58644, -75.68264, -75.56732, -75.59502, -75.37198,
                  -75.59585, -75.57081, -75.40989, -75.50928, -75.54841, -75.72734,
                  -75.36676, -75.79303, -75.36966, -75.69282, -75.42498, -75.57986,
                  -75.58644, -75.64551, -75.45509, -75.47098])
y_arr = np.array([38.07759, 38.07541, 38.06712, 38.09973, 38.06692, 38.09264,
                  38.08731, 38.0822, 38.36981, 38.06027, 38.07962, 38.08531,
                  37.93448, 38.07716, 37.71758, 38.08925, 38.0975, 38.33174,
                  38.05731, 38.05515, 38.0547, 38.1398, 38.066, 38.27009,
                  37.93415, 38.24889, 38.19691, 38.03272, 38.19954, 37.91286,
                  37.97847, 38.29755, 38.01239, 37.93453])
z_arr = np.array([17.526, 21.336, 19.558, 17.78, 20.828, 20.828, 20.066, 21.082,
                  18.542, 20.32, 19.812, 19.05, 16.51, 20.066, 25.654, 16.51,
                  18.542, 17.018, 20.828, 21.844, 21.59, 16.764, 20.828, 19.558,
                  19.812, 22.606, 25.146, 19.558, 20.574, 24.13, 35.306, 19.558,
                  23.876, 18.796])

resolution = 50

xx, yy = np.meshgrid(
    np.linspace(np.min(x_arr), np.max(x_arr), num=resolution),
    np.linspace(np.min(y_arr), np.max(y_arr), num=resolution)
)

falloff = 2
max_closeness = 100000


def eval_at_point(p_x, p_y):
    closeness = [min(np.hypot(x - p_x, y - p_y) ** -falloff, max_closeness) for x, y in zip(x_arr, y_arr)]

    return sum(close * z for close, z in zip(closeness, z_arr)) / sum(closeness)


zz = [[eval_at_point(x, y) for x, y in zip(x_row, y_row)] for x_row, y_row in zip(xx, yy)]
plt.scatter(x_arr, y_arr, c=z_arr)
plt.contour(xx, yy, zz)
plt.show()

contourf.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...