Как я могу сделать график рассеяния, окрашенный по плотности в matplotlib?
Я хотел бы сделать график рассеяния, где каждая точка окрашена пространственной плотностью соседних точек.
Я столкнулся с очень похожим вопросом, который показывает пример этого с помощью R:
R Scatter Plot: цвет символа представляет количество перекрывающихся точек
Какой лучший способ выполнить что-то подобное в python с помощью matplotlib?
Ответы
Ответ 1
В дополнение к hist2d
или hexbin
по предложению @askewchan вы можете использовать тот же метод, что и принятый ответ в вопросе, который вы связали с использованием.
Если вы хотите сделать это:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)
# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
fig, ax = plt.subplots()
ax.scatter(x, y, c=z, s=100, edgecolor='')
plt.show()
![enter image description here]()
Если вы хотите, чтобы точки были построены в порядке плотности, чтобы самые плотные точки всегда были сверху (аналогично связанному примеру), просто отсортируйте их по значениям z. Я также собираюсь использовать здесь меньший размер маркера, поскольку он выглядит немного лучше:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)
# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
# Sort the points by density, so that the densest points are plotted last
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
fig, ax = plt.subplots()
ax.scatter(x, y, c=z, s=50, edgecolor='')
plt.show()
![enter image description here]()
Ответ 2
Вы можете сделать гистограмму:
import numpy as np
import matplotlib.pyplot as plt
# fake data:
a = np.random.normal(size=1000)
b = a*3 + np.random.normal(size=1000)
plt.hist2d(a, b, (50, 50), cmap=plt.cm.jet)
plt.colorbar()
![2dhist]()
Ответ 3
Также, если количество точек делает вычисления KDE слишком медленными, цвет можно интерполировать в np.histogram2d:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interpn
def density_scatter( x , y, ax = None, sort = True, bins = 20, **kwargs ) :
"""
Scatter plot colored by 2d histogram
"""
if ax is None :
fig , ax = plt.subplots()
data , x_e, y_e = np.histogram2d( x, y, bins = bins)
z = interpn( ( 0.5*(x_e[1:] + x_e[:-1]) , 0.5*(y_e[1:]+y_e[:-1]) ) , data , np.vstack([x,y]).T , method = "splinef2d", bounds_error = False )
# Sort the points by density, so that the densest points are plotted last
if sort :
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
ax.scatter( x, y, c=z, **kwargs )
return ax
if "__main__" == __name__ :
x = np.random.normal(size=100000)
y = x * 3 + np.random.normal(size=100000)
density_scatter( x, y, bins = [30,30] )
![]()