Выполнение преобразования журнала для оси 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)

Другие вопросы по тегам