і початкове питання було ... як перетворити значення розкидання в значення сітки, правда?
histogram2d
обчислює частоту на комірку, однак, якщо у вас є інші дані на комірку, ніж просто частота, вам знадобиться додаткова робота.
x = data_x # between -10 and 4, log-gamma of an svc
y = data_y # between -4 and 11, log-C of an svc
z = data_z #between 0 and 0.78, f1-values from a difficult dataset
Отже, у мене є набір даних із Z-результатами для координат X та Y. Однак я підраховував декілька балів за межами області, що цікавить (великі прогалини), і купи балів на невеликій цікавій області.
Так, тут стає важче, але й веселіше. Деякі бібліотеки (вибачте):
from matplotlib import pyplot as plt
from matplotlib import cm
import numpy as np
from scipy.interpolate import griddata
pyplot - це мій графічний двигун сьогодні, cm - це діапазон кольорових карт з певним цікавим вибором. numpy для обчислень та griddata для приєднання значень до нерухомої сітки.
Останнє важливе, особливо тому, що частота точок xy в моїх даних не однаково розподілена. Спочатку почнемо з деяких меж, що відповідають моїм даним та довільного розміру сітки. У вихідних даних є точки даних також поза межами x та y.
#determine grid boundaries
gridsize = 500
x_min = -8
x_max = 2.5
y_min = -2
y_max = 7
Отже, ми визначили сітку з 500 пікселями між значеннями min та max x та y.
За моїми даними, є набагато більше, ніж 500 значень, доступних у зоні, що викликає великий інтерес; оскільки в зоні з низьким рівнем інтересу в загальній сітці немає навіть 200 значень; між графічними межами x_min
та x_max
і ще менше.
Тож для отримання гарної картини завдання полягає в тому, щоб отримати середнє значення за високими відсотковими значеннями та заповнити прогалини в інших місцях.
Я визначаю свою сітку зараз. Для кожної пари xx-yy я хочу мати колір.
xx = np.linspace(x_min, x_max, gridsize) # array of x values
yy = np.linspace(y_min, y_max, gridsize) # array of y values
grid = np.array(np.meshgrid(xx, yy.T))
grid = grid.reshape(2, grid.shape[1]*grid.shape[2]).T
Чому дивна форма? scipy.griddata хоче форму (n, D).
Griddata обчислює одне значення на точку в сітці заздалегідь визначеним методом. Я вибираю "найближчий" - порожні точки сітки заповняться значеннями від найближчого сусіда. Це виглядає так, ніби області з меншою кількістю інформації мають більші комірки (навіть якщо це не так). Можна було б інтерполювати "лінійні", тоді області з меншою кількістю інформації виглядають менш гостро. Справа смаку, дійсно.
points = np.array([x, y]).T # because griddata wants it that way
z_grid2 = griddata(points, z, grid, method='nearest')
# you get a 1D vector as result. Reshape to picture format!
z_grid2 = z_grid2.reshape(xx.shape[0], yy.shape[0])
І скакаємо, ми передаємо matplotlib для відображення сюжету
fig = plt.figure(1, figsize=(10, 10))
ax1 = fig.add_subplot(111)
ax1.imshow(z_grid2, extent=[x_min, x_max,y_min, y_max, ],
origin='lower', cmap=cm.magma)
ax1.set_title("SVC: empty spots filled by nearest neighbours")
ax1.set_xlabel('log gamma')
ax1.set_ylabel('log C')
plt.show()
Навколо точкової частини V-Shape ви бачите, що я зробив багато розрахунків під час пошуку солодкого місця, тоді як менш цікаві частини майже скрізь мають нижчу роздільну здатність.