在 Matplotlib 中使用对数 x 数据绘制 KDE
Plotting KDE with logarithmic x-data in Matplotlib
我想为一些数据绘制一个 KDE,其中数据的 x 值范围很大。因此我想对 x 轴使用对数刻度。为了绘图,我使用了 seaborn 和来自 的解决方案,一旦我将 xscale 设置为对数,这两者都会失败。当我事先取 x 数据的对数时,一切看起来都很好,除了 tic 和 ticlabels 仍然与作为标签的实际值的对数成线性关系。我可以使用类似以下内容手动更改抽动:
labels = np.array(ax.get_xticks().tolist(), dtype=np.float64)
new_labels = [r'^{%.1f}$' % (labels[i]) for i in range(len(labels))]
ax.set_xticklabels(new_labels)
但在我看来,这看起来是错误的,并且当我只是使用
ax.set_xscale('log')
有没有更简单的方法来绘制具有对数 x 数据的 KDE?或者是否可以只更改 tic- 或标签比例而不更改数据的比例,这样我就可以绘制 x 的对数值并随后更改标签的比例?
编辑:
我要创建的情节如下所示:
右边的两列是它应该看起来的样子。在那里我使用了已经应用对数的 x 数据。不过,我不喜欢 x 轴上的标签。
左栏显示的是原始数据用于 kde 和所有其他绘图的绘图,之后使用
更改比例
ax.set_xscale('log')
出于某种原因,kde 看起来不像它应该的样子。这也不是错误数据的结果,因为如果使用对数数据,它看起来就很好。
编辑 2:
代码的一个工作示例是
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data = np.random.multivariate_normal((0, 0), [[0.8, 0.05], [0.05, 0.7]], 100)
x = np.power(10, data[:, 0])
y = data[:, 1]
fig, ax = plt.subplots(2, 1)
sns.kdeplot(data=np.log10(x), data2=y, ax=ax[0])
sns.kdeplot(data=x, data2=y, ax=ax[1])
ax[1].set_xscale('log')
plt.show()
ax[1]
图对我来说显示不正确(x 轴反转),但一般行为与上述情况相同。我相信问题出在 kde 的带宽上,它可能应该考虑对数 x 数据。
我找到了一个适合我的答案,并想 post 以防其他人遇到类似问题。
根据 post 接受的答案,我定义了一个函数,该函数首先将对数应用于 x 数据,并在执行 KDE 后,将 x 值转换回原始值。之后我可以简单地绘制轮廓并使用 ax.set_xscale('log')
import numpy as np
import scipy.stats as st
def logx_kde(x, y, xmin, xmax, ymin, ymax):
x = np.log10(x)
# Peform the kernel density estimate
xx, yy = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([xx.ravel(), yy.ravel()])
values = np.vstack([x, y])
kernel = st.gaussian_kde(values)
f = np.reshape(kernel(positions).T, xx.shape)
return np.power(10, xx), yy, f
我想为一些数据绘制一个 KDE,其中数据的 x 值范围很大。因此我想对 x 轴使用对数刻度。为了绘图,我使用了 seaborn 和来自
labels = np.array(ax.get_xticks().tolist(), dtype=np.float64)
new_labels = [r'^{%.1f}$' % (labels[i]) for i in range(len(labels))]
ax.set_xticklabels(new_labels)
但在我看来,这看起来是错误的,并且当我只是使用
ax.set_xscale('log')
有没有更简单的方法来绘制具有对数 x 数据的 KDE?或者是否可以只更改 tic- 或标签比例而不更改数据的比例,这样我就可以绘制 x 的对数值并随后更改标签的比例?
编辑:
我要创建的情节如下所示:
左栏显示的是原始数据用于 kde 和所有其他绘图的绘图,之后使用
更改比例ax.set_xscale('log')
出于某种原因,kde 看起来不像它应该的样子。这也不是错误数据的结果,因为如果使用对数数据,它看起来就很好。
编辑 2: 代码的一个工作示例是
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data = np.random.multivariate_normal((0, 0), [[0.8, 0.05], [0.05, 0.7]], 100)
x = np.power(10, data[:, 0])
y = data[:, 1]
fig, ax = plt.subplots(2, 1)
sns.kdeplot(data=np.log10(x), data2=y, ax=ax[0])
sns.kdeplot(data=x, data2=y, ax=ax[1])
ax[1].set_xscale('log')
plt.show()
ax[1]
图对我来说显示不正确(x 轴反转),但一般行为与上述情况相同。我相信问题出在 kde 的带宽上,它可能应该考虑对数 x 数据。
我找到了一个适合我的答案,并想 post 以防其他人遇到类似问题。
根据 ax.set_xscale('log')
import numpy as np
import scipy.stats as st
def logx_kde(x, y, xmin, xmax, ymin, ymax):
x = np.log10(x)
# Peform the kernel density estimate
xx, yy = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([xx.ravel(), yy.ravel()])
values = np.vstack([x, y])
kernel = st.gaussian_kde(values)
f = np.reshape(kernel(positions).T, xx.shape)
return np.power(10, xx), yy, f