แก้ไข: เพื่อการประมาณที่ดีขึ้นของคำตอบของ Alejandro ดูด้านล่าง
ฉันรู้ว่านี่เป็นคำถามเก่า แต่ต้องการเพิ่มบางสิ่งบางอย่างใน Anwser ของ Alejandro: หากคุณต้องการภาพที่ราบรื่นโดยไม่ใช้ py-sphviewer คุณสามารถใช้np.histogram2d
และใช้ตัวกรอง gaussian (จากscipy.ndimage.filters
) ลงใน heatmap แทน
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.ndimage.filters import gaussian_filter
def myplot(x, y, s, bins=1000):
heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
heatmap = gaussian_filter(heatmap, sigma=s)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
return heatmap.T, extent
fig, axs = plt.subplots(2, 2)
# Generate some test data
x = np.random.randn(1000)
y = np.random.randn(1000)
sigmas = [0, 16, 32, 64]
for ax, s in zip(axs.flatten(), sigmas):
if s == 0:
ax.plot(x, y, 'k.', markersize=5)
ax.set_title("Scatter plot")
else:
img, extent = myplot(x, y, s)
ax.imshow(img, extent=extent, origin='lower', cmap=cm.jet)
ax.set_title("Smoothing with $\sigma$ = %d" % s)
plt.show()
ผลิต:
พล็อตกระจายและ s = 16 พล็อตที่ด้านบนของ eachother สำหรับ Agape Gal'lo (คลิกเพื่อดูดีกว่า):
ข้อแตกต่างประการหนึ่งที่ฉันสังเกตเห็นด้วยวิธีตัวกรองแบบเกาส์เซียนและแนวทางของ Alejandro คือวิธีการของเขาแสดงให้เห็นโครงสร้างในท้องถิ่นดีกว่าของฉันมาก ดังนั้นฉันจึงใช้วิธีเพื่อนบ้านที่ใกล้เคียงที่สุดที่ระดับพิกเซล วิธีนี้จะคำนวณผลรวมผกผันของระยะทางของn
จุดที่ใกล้ที่สุดในแต่ละพิกเซลสำหรับแต่ละพิกเซล วิธีนี้มีความละเอียดสูงค่อนข้างแพงและฉันคิดว่ามันมีวิธีที่เร็วกว่าดังนั้นแจ้งให้เราทราบหากคุณมีการปรับปรุงใด ๆ
ปรับปรุง: ขณะที่ผมสงสัยว่ามีวิธีได้เร็วขึ้นมากโดยใช้ scipy.cKDTree
SciPy ดูคำตอบของ Gabrielสำหรับการนำไปใช้
อย่างไรก็ตามนี่คือรหัสของฉัน:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
def data_coord2view_coord(p, vlen, pmin, pmax):
dp = pmax - pmin
dv = (p - pmin) / dp * vlen
return dv
def nearest_neighbours(xs, ys, reso, n_neighbours):
im = np.zeros([reso, reso])
extent = [np.min(xs), np.max(xs), np.min(ys), np.max(ys)]
xv = data_coord2view_coord(xs, reso, extent[0], extent[1])
yv = data_coord2view_coord(ys, reso, extent[2], extent[3])
for x in range(reso):
for y in range(reso):
xp = (xv - x)
yp = (yv - y)
d = np.sqrt(xp**2 + yp**2)
im[y][x] = 1 / np.sum(d[np.argpartition(d.ravel(), n_neighbours)[:n_neighbours]])
return im, extent
n = 1000
xs = np.random.randn(n)
ys = np.random.randn(n)
resolution = 250
fig, axes = plt.subplots(2, 2)
for ax, neighbours in zip(axes.flatten(), [0, 16, 32, 64]):
if neighbours == 0:
ax.plot(xs, ys, 'k.', markersize=2)
ax.set_aspect('equal')
ax.set_title("Scatter Plot")
else:
im, extent = nearest_neighbours(xs, ys, resolution, neighbours)
ax.imshow(im, origin='lower', extent=extent, cmap=cm.jet)
ax.set_title("Smoothing over %d neighbours" % neighbours)
ax.set_xlim(extent[0], extent[1])
ax.set_ylim(extent[2], extent[3])
plt.show()
ผลลัพธ์: