如何在一个窗口中绘制多个seaborn`distplot`?

时间:2020-09-15 22:56:13

标签: python matplotlib seaborn

我正在尝试在一个窗口中绘制多个seaborn distplot。 我知道如何为单个数据列表生成密度图,如下面的代码所示(make_density函数)。 但是,我不确定如何在单个窗口下绘制多个seaborn distplots。 假设我的列表stat_list包含6个列表作为元素,我想在distplot下的这6个列表中每个绘制一个stat_list。如何在同一窗口下绘制6个displots,每行显示3个图(这样我的输出将有2行,共3个图)?

谢谢


# function to plot the histogram for a single list.
def make_density(stat_list, color, x_label, y_label):
    
    # Plot formatting
    plt.xlabel(x_label)
    plt.ylabel(y_label)

    # Draw the histogram and fit a density plot.
    sns.distplot(stat_list, hist = True, kde = True,
                 kde_kws = {'linewidth': 2}, color=color)
    
    # get the y-coordinates of the points of the density curve.
    dens_list = sns.distplot(stat_list, hist = False, kde = False,
             kde_kws = {'linewidth': 2}, color = color).get_lines()[0].get_data()[1].tolist()
        
    # find the maximum y-coordinates of the density curve.            
    max_dens_index = dens_list.index(max(dens_list))
    
    # find the mode of the density plot.
    mode_x = sns.distplot(stat_list, hist = False, kde = False,
             kde_kws = {'linewidth': 2}, color = color).get_lines()[0].get_data()[0].tolist()[max_dens_index]
    
    # draw a vertical line at the mode of the histogram.
    plt.axvline(mode_x, color='blue', linestyle='dashed', linewidth=1.5)
    plt.text(mode_x * 1.05, 0.16, 'Mode: {:.4f}'.format(mode_x))

# `stat_list` is a list of 6 lists
# I want to draw histogram and density plot of 
# each of these 6 lists contained in `stat_list` in a single window,
# where each row containing the histograms and densities of the 3 plots
# so in my example, there would be 2 rows of 3 columns of plots (2 x 3 =6).
stat_list = [[0.3,0.5,0.7,0.3,0.5],[0.2,0.1,0.9,0.7,0.4],[0.9,0.8,0.7,0.6,0.5]
          [0.2,0.6,0.75,0.87,0.91],[0.2,0.3,0.8,0.9,0.3],[0.2,0.3,0.8,0.87,0.92]]

2 个答案:

答案 0 :(得分:1)

我将为此使用seaborn的FacetGrid类。

简单版本:

import seaborn
seaborn.set(style='ticks', context='paper')

axgrid = (
    seaborn.load_dataset('titanic')
        .pipe(seaborn.FacetGrid, hue='deck', col='deck', col_wrap=3, sharey=False)
        .map(seaborn.distplot, 'fare')
)

或对功能进行了一些修改:

from matplotlib import pyplot
import seaborn
seaborn.set(style='ticks', context='paper')


# function to plot the histogram for a single list.
def make_density(stat, color=None, x_label=None, y_label=None, ax=None, label=None):
   
    if not ax:
        ax = pyplot.gca()
    # Draw the histogram and fit a density plot.
    seaborn.distplot(stat, hist=True, kde=True,
                     kde_kws={'linewidth': 2}, color=color, ax=ax)

    # get the y-coordinates of the points of the density curve.
    dens_list = ax.get_lines()[0].get_data()[1]

    # find the maximum y-coordinates of the density curve.
    max_dens_index = dens_list.argmax()

    # find the mode of the density plot.
    mode_x = ax.get_lines()[0].get_data()[0][max_dens_index]

    # draw a vertical line at the mode of the histogram.
    ax.axvline(mode_x, color=color, linestyle='dashed', linewidth=1.5)
    ymax = ax.get_ylim()[1]
    ax.text(mode_x * 1.1, ymax * 0.16, 'Mode: {:.4f}'.format(mode_x))

    # Plot formatting
    ax.set_xlabel(x_label)
    ax.set_ylabel(y_label)


axgrid = (
    seaborn.load_dataset('titanic')
        .pipe(seaborn.FacetGrid, hue='deck', col='deck', col_wrap=3, sharey=False)
        .map(make_density, 'fare')
)

enter image description here

答案 1 :(得分:0)

您可以使用fig, axes = plt.subplots(...)创建子图网格。然后,您可以将返回的“轴”的每个“轴”提供为ax=的{​​{1}}参数。请注意,您将需要使用相同的sns.distplot()来设置标签,ax仅会更改其中一个子图。

不建议致电plt.xlabel()三次。 sns.distplot将向同一sns.distplot添加越来越多的信息。还要注意,您可以使用argmax()之类的numpy函数来高效地找到最大值,而无需转换为Python列表(当有大量数据时,这会很慢)。

ax

resulting plot

PS:也可以使用import matplotlib.pyplot as plt import seaborn as sns import numpy as np # function to plot the histogram for a single list. def make_density(stat, color, x_label, y_label, ax): # Draw the histogram and fit a density plot. sns.distplot(stat, hist=True, kde=True, kde_kws={'linewidth': 2}, color=color, ax=ax) # get the y-coordinates of the points of the density curve. dens_list = ax.get_lines()[0].get_data()[1] # find the maximum y-coordinates of the density curve. max_dens_index = dens_list.argmax() # find the mode of the density plot. mode_x = ax.get_lines()[0].get_data()[0][max_dens_index] # draw a vertical line at the mode of the histogram. ax.axvline(mode_x, color='blue', linestyle='dashed', linewidth=1.5) ax.text(mode_x * 1.05, 0.16, 'Mode: {:.4f}'.format(mode_x)) # Plot formatting ax.set_xlabel(x_label) ax.set_ylabel(y_label) stat_list = [[0.3, 0.5, 0.7, 0.3, 0.5], [0.2, 0.1, 0.9, 0.7, 0.4], [0.9, 0.8, 0.7, 0.6, 0.5], [0.2, 0.6, 0.75, 0.87, 0.91], [0.2, 0.3, 0.8, 0.9, 0.3], [0.2, 0.3, 0.8, 0.87, 0.92]] num_subplots = len(stat_list) ncols = 3 nrows = (num_subplots + ncols - 1) // ncols fig, axes = plt.subplots(ncols=ncols, nrows=nrows, figsize=(ncols * 6, nrows * 5)) colors = plt.cm.tab10.colors for ax, stat, color in zip(np.ravel(axes), stat_list, colors): make_density(stat, color, 'x_label', 'y_label', ax) for ax in np.ravel(axes)[num_subplots:]: # remove possible empty subplots at the end ax.remove() plt.show() (Seaborn distplot中的新功能)来代替histplot。这应该给出更好的图,尤其是在数据很少和/或离散的情况下。

0.11

histplot