如何使用seaborn绘制配对直方图

Sam*_*ria 6 python matplotlib histogram seaborn

我想使用seaborn distplot制作一个配对直方图,如下所示这种图也可称为此处所示的背对背直方图,或如此处所讨论的沿 x 轴反转/镜像的双直方图

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

green = np.random.normal(20,10,1000)
blue = np.random.poisson(60,1000)

fig, ax = plt.subplots(figsize=(8,6))

sns.distplot(blue, hist=True, kde=True, hist_kws={'edgecolor':'black'}, kde_kws={'linewidth':2}, bins=10, color='blue')
sns.distplot(green, hist=True, kde=True, hist_kws={'edgecolor':'black'}, kde_kws={'linewidth':2}, bins=10, color='green')
ax.set_xticks(np.arange(-20,121,20))
ax.set_yticks(np.arange(0.0,0.07,0.01))
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.show()
Run Code Online (Sandbox Code Playgroud)

这是输出: Seaborn分布图

当我使用此处讨论的方法(plt.barh)时,我得到了下面显示的条形图,这不是我想要的。 水平条形图

或者也许我还没有很好地理解解决方法......类似于这些类型的图的 python-seaborn-distplot 的简单/简短实现将是完美的。我编辑了上面第一个图的图,以显示我希望实现的图类型(尽管 y 轴没有颠倒): 配对直方图

任何线索将不胜感激。

war*_*ped 7

您可以使用两个子图并反转下一个子图的 y 轴并使用相同的箱进行绘图。

df = pd.DataFrame({'a': np.random.normal(0,5,1000), 'b': np.random.normal(20,5,1000)})

fig =plt.figure(figsize=(5,5))
ax = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

bins = np.arange(-20,40)

ax.hist(df['a'], bins=bins)
ax2.hist(df['b'],color='orange', bins=bins)
ax2.invert_yaxis()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

编辑:

@mwaskom 建议的改进

fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True, figsize=(5,5))

bins = np.arange(-20,40)

for ax, column, color, invert in zip(axes.ravel(), df.columns, ['teal', 'orange'],  [False,True]):
    ax.hist(df[column], bins=bins, color=color)
    
    if invert:
        ax.invert_yaxis()
        
plt.subplots_adjust(hspace=0)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Joh*_*anC 6

这是使用seaborn 的displots 的可能方法。Seaborn 不会返回创建的图形元素,但ax可以对其进行询问。为了确保ax只包含您想要颠倒的元素,可以先绘制这些元素。然后,所有patches(矩形条)和lines(kde 曲线)的高度都可以为负值。y == 0可以选择使用来设置 x 轴ax.spines['bottom'].set_position('zero')

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

green = np.random.normal(20, 10, 1000)
blue = np.random.poisson(60, 1000)

fig, ax = plt.subplots(figsize=(8, 6))

sns.distplot(green, hist=True, kde=True, hist_kws={'edgecolor': 'black'}, kde_kws={'linewidth': 2}, bins=10,
             color='green')
for p in ax.patches:  # turn the histogram upside down
    p.set_height(-p.get_height())
for l in ax.lines:  # turn the kde curve upside down
    l.set_ydata(-l.get_ydata())

sns.distplot(blue, hist=True, kde=True, hist_kws={'edgecolor': 'black'}, kde_kws={'linewidth': 2}, bins=10,
             color='blue')
ax.set_xticks(np.arange(-20, 121, 20))
ax.set_yticks(np.arange(0.0, 0.07, 0.01))
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

pos_ticks = np.array([t for t in ax.get_yticks() if t > 0])
ticks = np.concatenate([-pos_ticks[::-1], [0], pos_ticks])
ax.set_yticks(ticks)
ax.set_yticklabels([f'{abs(t):.2f}' for t in ticks])
ax.spines['bottom'].set_position('zero')

plt.show()
Run Code Online (Sandbox Code Playgroud)

示例图