如何在一个窗口中绘制多个seaborn`distplot`? [英] how to draw multiple seaborn `distplot` in a single window?

查看:128
本文介绍了如何在一个窗口中绘制多个seaborn`distplot`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

谢谢,

 #函数绘制单个列表的直方图.def make_density(stat_list,color,x_label,y_label):#绘图格式plt.xlabel(x_label)plt.ylabel(y_label)# 绘制直方图并拟合密度图.sns.distplot(stat_list, hist = True, kde = True,kde_kws = {'linewidth':2},color = color)# 获取密度曲线各点的 y 坐标.dens_list = sns.distplot(stat_list,hist = False,kde = False,kde_kws = {'linewidth':2},颜色=颜色).get_lines()[0] .get_data()[1] .tolist()#找到密度曲线的最大y坐标.max_dens_index = dens_list.index(max(dens_list))#查找密度图的模式.mode_x = sns.distplot(stat_list, hist = False, kde = False,kde_kws = {'linewidth':2},颜色=颜色).get_lines()[0] .get_data()[0] .tolist()[max_dens_index]#在直方图的模式下绘制一条垂直线.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` 是一个包含 6 个列表的列表#我要绘制直方图和密度图# 在单个窗口中包含在 `stat_list` 中的这 6 个列表中的每一个,# 其中每一行包含 3 个图的直方图和密度#因此,在我的示例中,将有2行3列的图(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]]

解决方案

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

不建议调用 sns.distplot 3 次.sns.distplot 会在同一个 ax 中添加越来越多的信息.另请注意,您可以使用numpy函数,例如

PS:也可以使用 histplot(Seaborn 0.11 中的新功能)代替 distplot.这应该给出更好的图,尤其是在数据很少和/或离散的情况下.

sns.histplot(stat, kde=True, line_kws={'linewidth': 2}, color=color, ax=ax)

I am trying to draw multiple seaborn distplot in a single window. I know how to generate a density plot for a single list of data, as shown in my code below (make_density function). However, I am not sure how to draw multiple seaborn distplots under a single window. Suppose that my list stat_list contains 6 lists as its element, where I want to draw a single distplot from each of these 6 lists under stat_list. How can I draw the 6 displots under a same window, where 3 plots are displayed in each row (so that my output would have 2 rows of 3 plots)?

Thank you,


# 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]]

解决方案

You can create a grid of subplots with fig, axes = plt.subplots(...). Then you can provide each 'ax' of the returned 'axes' as the ax= parameter of sns.distplot(). Note that you'll need the same ax to set the labels, plt.xlabel() will only change one of the subplots.

Calling sns.distplot three times is not recommended. sns.distplot will add more and more information to the same ax. Also note that you can use numpy functions such as argmax() to efficiently find the maximum without the need to convert to Python lists (which are quite slow when there is a lot of data).

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()

PS: Instead of distplot also histplot (new in Seaborn 0.11) could be used. This should give a nicer plot, especially when the data are few and/or discrete.

sns.histplot(stat, kde=True, line_kws={'linewidth': 2}, color=color, ax=ax)

这篇关于如何在一个窗口中绘制多个seaborn`distplot`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆