Выполнение преобразования журнала для оси Z в sns.kdeplot
Я пытаюсь выполнить преобразование журнала по оси z для данного графика, чтобы я мог видеть данные, представленные на графике, где они разрежены. Но я не понимаю, как это сделать.
sns.kdeplot( x , y , cmap='gist_gray_r', shade=True, shade_lowest=False)
Изображение сверху команды прикреплено ниже (x, y - 2 списка данных). Может ли кто-нибудь помочь с преобразованием журнала (т.е.) применить журнал к оси z.
1 ответ
Kdeplot Seaborn не сможет напрямую учитывать журнал. Но вы можете вручную вызвать kde, вычислить значение по сетке и взять журнал. А потом вручную создайте контурный участок.
Однако, если массивы x и y не слишком велики, kde не будет иметь много значимой информации в разреженных областях. Все разгладится.
Другая идея - это scatterplot
. Использование маркера запятой (marker=','
) и удаление краев точек (linewidth=0
) можно нарисовать очень маленькие точки. В зависимости от количества точек может использоваться альфа меньшего размера. Точечная диаграмма имеет то преимущество, что показывает данные такими, какие они есть на самом деле, вместо произвольного приближения с помощью kde.
В приведенном ниже коде создается пример трех подходов. Оси X и Y являются общими, чтобы показать гораздо большую площадь, занимаемую уровнями логарифмической шкалы.
from matplotlib import pyplot as plt
import numpy as np
import seaborn as sns
from scipy.stats import gaussian_kde
x = np.random.normal(np.tile([0.02, 0.03, 0.04, 0.06], 10000), 0.01)
y = np.random.normal(np.tile([-0.5, 0.5, 1, 0.9], 10000), 0.4)
fig, axes = plt.subplots(ncols=3, figsize=(14, 4), sharex=True, sharey=True)
# create a regular kdeplot
sns.kdeplot(x, y, cmap='gist_gray_r', shade=True, shade_lowest=False, ax=axes[0])
axes[0].set_title('standard kdeplot')
# create a kdeplot with logscale levels
kde = gaussian_kde([x, y])
xmin, xmax = x.min() - 0.02, x.max() + 0.02
ymin, ymax = y.min() - 0.8, y.max() + 0.8
xs, ys = np.meshgrid(np.linspace(xmin, xmax, 50), np.linspace(ymin, ymax, 50))
z = kde([xs.ravel(), ys.ravel()]).reshape(xs.shape)
N = 10
levels = np.logspace(-6, np.log10(z.max()), N + 1)
cmap = plt.get_cmap('inferno_r', N)
axes[1].contourf(xs, ys, z, levels=levels, colors=[cmap((i + 1) / N) for i in range(N)], alpha=0.5)
axes[1].yaxis.set_tick_params(labelleft=True) # 'sharey' removes the ticks, here they are added again
axes[1].set_title('kdeplot with logscale levels')
# draw a scatter plot
sns.scatterplot(x, y, color='r', marker=',', linewidth=0, s=1, alpha=0.2, ax=axes[2])
axes[2].yaxis.set_tick_params(labelleft=True)
axes[2].set_title('scatterplot')
plt.show()
Другая идея - объединить обычный kdeplot с диаграммой рассеяния для удаленных точек:
ax = sns.kdeplot(x, y, cmap='gist_gray_r', shade=True, shade_lowest=False)
sns.scatterplot(x, y, color='grey', marker=',', linewidth=0, s=1, alpha=1, zorder=0, ax=ax)