【问题标题】:How to plot multiple seaborn.distplot in a single figure如何在单个图中绘制多个 seaborn.distplot
【发布时间】:2021-01-03 12:37:25
【问题描述】:

我想在同一个窗口下绘制多个 seaborn distplot,其中每个图都有相同的 x 和 y 网格。我的尝试如下所示,但不起作用。

# function to plot the density curve of the 200 Median Stn. MC-losses
def make_density(stat_list,color, layer_num):

    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))
    
    for i in range(len(stat_list)):
        
        # Plot formatting
        plt.title('Layer ' + layer_num)
        plt.xlabel('Median Stn. MC-Loss')
        plt.ylabel('Density')
        plt.xlim(-0.2,0.05)
        plt.ylim(0, 85)
        min_ylim, max_ylim = plt.ylim()
    
        # Draw the density plot.
        sns.distplot(stat_list, hist = True, kde = True,
                 kde_kws = {'linewidth': 2}, color=color)

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

如何修改我的函数以在同一窗口下绘制多个distplot,其中每个显示图的 x 和 y 网格相同?

谢谢,

PS:除此之外,我希望 6 个分布图具有相同的颜色,最好都是绿色。

【问题讨论】:

  • 这在your previous question 看来非常强烈,但你没有使用for ax in axes,而且你也没有使用sns.distplot(...., ax=ax)。您可以使用plt.subplots(...., sharex=True, sharey=True) 共享 x 和 y 轴。您的示例代码似乎只使用了一种颜色。注意plt.xlim等需要放在创建主图之后,而不是之前。当只有一个子图时,plt.xlim 等效于 ax.set_xlim

标签: python matplotlib seaborn


【解决方案1】:
  • 最简单的方法是将数据加载到pandas中,然后使用seaborn.displot
  • .displot 在 seaborn 版本 0.11.0 中替换 .distplot
    • 从技术上讲,您之前想要的是 FacetGrid 映射到 distplot
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

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

# load the data into pandas and then transpose it for the correct column data
df = pd.DataFrame(stat_list).T

# name the columns; specify a layer number
df.columns = ['A', 'B', 'C', 'D', 'E', 'F']

# now stack the data into a long (tidy) format
dfl = df.stack().reset_index(level=1).rename(columns={'level_1': 'Layer', 0: 'Median Stn. MC-Loss'})

# plot a displot
g = sns.displot(data=dfl, x='Median Stn. MC-Loss', col='Layer', col_wrap=3, kde=True, color='green')
g.set_axis_labels(y_var='Density')
g.set(xlim=(0, 1.0), ylim=(0, 3.0))

sns.FacetGridsns.distplot

  • .distplot 已弃用
p = sns.FacetGrid(data=dfl, col='Layer', col_wrap=3, height=5)
p.map(sns.distplot, 'Median Stn. MC-Loss', bins=5, kde=True, color='green')
p.set(xlim=(0, 1.0))

【讨论】:

  • 我注意到前三个图(从第一行开始)缺少 x 轴值。如何启用它们?
  • @meW 这个answer 展示了如何将 xtick 标签添加到 FacetGrid 的每一行。查看最后 3 行代码。
【解决方案2】:

这里有一个通用解决方案,即包含 17 个 matplotlib 图形实用程序 + 用户指南的免费库:https://www.mlbridgeresearch.com/products/free-article-2。我厌倦了为了编写实用软件而中断研究,因此我积累了满足常见需求的库。该代码有据可查,并且运行良好。 该示例在库中调用 histogram_grid(),它返回 matplotlib 图上的绘图网格。由于直方图通常没有相同的范围,标准方法不能完全满足您的要求,因此对返回的图进行了调整。

import pandas as pd
import matplotlib.pyplot as plt

from statistics_utilities import histogram_grid


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

df = pd.DataFrame(stat_list).transpose()
# histogram_grid() accepts only a DataFrame and requires named columns.
df.columns = ['x1', 'x2', 'x3', 'x4', 'x5', 'x6']

# If kde is True, the plot is a density plot no matter how hist_type is set.
hist_type = 'density'
variable_names = df.columns
bins = 3
fig = histogram_grid(df, bins=bins, hist_type=hist_type, kde=True, legend=False,
                     title='test title', variable_names=variable_names,
                     n_gridcolumns=3, height=6, width=10)
fig.subplots_adjust(wspace=.2, left=0.035, right=.95, bottom=.13)

# the adjustments to the axes on the 2 x 3 grid plot.
# Turn of x-axis labels/ticks in the top row and y-axis
# labels/ticks in the 1st column.
axes_list = fig.axes            # get a list of Axes in Figure
ax_index = 0
modify_xaxes_indexes = [0, 1, 2]
modify_yaxes_indexes = [1, 2, 4, 5]
for ax in axes_list:
    ax.set_xlabel(None)
    ax.set_ylabel(None)
    # normally, the xlim() would be calculated but I can see that
    # .1 <= x <= .92 and similarly the densities are 0 <= y <= 3.
    ax.set_xlim(.05, .95)
    ax.set_ylim(0, 3)
    if ax_index in modify_xaxes_indexes:
        ax.tick_params(
            axis='x',  # changes apply to the x-axis
            which='both',  # both major and minor ticks are affected
            bottom=False,  # ticks along the bottom edge are off
            top=False,  # ticks along the top edge are off
            labelbottom=False)  # labels along the bottom edge are off
    if ax_index in modify_yaxes_indexes:
        ax.tick_params(
            axis='y',  # changes apply to the x-axis
            which='both',  # both major and minor ticks are affected
            left=False,  # ticks along the bottom edge are off
            right=False,  # ticks along the top edge are off
            labelleft=False)  # labels along the bottom edge are off
    ax_index += 1

plt.show()
plt.close()

【讨论】:

    猜你喜欢
    • 2021-04-21
    • 2013-08-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    相关资源
    最近更新 更多