Matplotlib Pandas:3 列的子图,每列是 3 行的子图

Matplotlib Pandas: Subplots of 3 columns and each column is a subplot of 3 rows

我有以下 pandas 数据框:

我的目标是将数据框绘制成 3 列,其中每列是一个 'section'。同时,每个图都是 3 行 1 列的子图,其中一行是 'Col1 [%]',第二行是 'Col 2',最后是 'Col 3 [%]'

如果我设置 subplots=True,我得到以下图:

否则,使用 subplots=False,我得到:

但我需要的是获得 3 列,但每列图都等于 suplots=True 的图形。我该怎么做?

非常感谢!

我的代码:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

# DATA
dfplot = pd.DataFrame(columns = ['section', 'description', 'Col1 [%]', 'Col 2', 'Col 3 [%]'])
dfplot['description'] = ['d1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9']
dfplot['section'] = [1, 1, 1, 2, 2, 2, 3, 3, 3]
dfplot['Col1 [%]'] = [82, 89, 86, 100, 100, 99, 16, 16, 16]
dfplot['Col 2'] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
dfplot['Col 3 [%]'] = [99.19, 98.7, 99.36, 99.9, 99.93, 99.5, 97.66, 97.84, 97.66]
dfplot = dfplot.groupby(['section', 'description'], as_index=True).last()


# PLOT -------------

# Set levels to group labels in ax X
cols = list(set(l_columns_values))
dfplot.index.set_levels([cols, l_strains], level=[0,1])

fig, axes = plt.subplots(nrows=1, ncols=len(cols), 
                         sharey=True, sharex=True, 
                         figsize=(14 / 2.54, 10 / 2.54) # width, height
                        )  

for i, col in enumerate(list(set(l_contigs))):
    ax = axes[i] #, j]
    
    print(ax)
    print("i= {}, col= {}".format(i, col))

    dfplot.loc[col].plot.area(ax=ax,
                              #layout=(3, 1),
                              stacked=True, 
                              subplots=True, ## <--     
                              grid=True,
                              table=False,
                              sharex=True,
                              sharey=True,
                              figsize=(20,7),
                              fontsize=12,
                              #xticks = np.arange(0, len(cols)+1, 1)
                             )
    #ax[i].set_ylim(-1,100)
    ax.set_xlabel(col, weight='bold', fontsize=20)
    ax.set_axisbelow(True)    

    for tick in ax.get_xticklabels():
        tick.set_rotation(90)

# make the ticklines invisible
ax.tick_params(axis=u'both', which=u'both', length=0)
plt.tight_layout()

# remove spacing in between
fig.subplots_adjust(wspace=0.5)  # space between plots

# legend
plt.legend(loc='upper right')

# Add title
fig.suptitle('My title')

plt.show()    

一些解释 - 每个列和部分的图表。

您的代码中存在问题 - 您正在覆盖 ax 数组并引用它。我使用了不同的变量名:axt

dfplot = pd.DataFrame(columns = ['section', 'description', 'Col1 [%]', 'Col 2', 'Col 3 [%]'])
dfplot['description'] = ['d1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9']
dfplot['section'] = [1, 1, 1, 2, 2, 2, 3, 3, 3]
dfplot['Col1 [%]'] = [82, 89, 86, 100, 100, 99, 16, 16, 16]
dfplot['Col 2'] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
dfplot['Col 3 [%]'] = [99.19, 98.7, 99.36, 99.9, 99.93, 99.5, 97.66, 97.84, 97.66]
# dfplot = dfplot.groupby(['section', 'description'], as_index=True).last()
dfplot = dfplot.set_index(["section", "description"])

fig, ax = plt.subplots(len(dfplot.index.get_level_values(0).unique()),len(dfplot.columns), figsize=[20,5],
                      sharey=True, sharex=False)

# Add title
fig.suptitle('My title')

for i,v in enumerate(dfplot.index.get_level_values(0).unique()):
    for j, c in enumerate(dfplot.columns):
        axt = ax[j][i]
        dfplot.loc[(v),[c]].plot.area(ax=axt, stacked=True)
        axt.set_xlabel(f"Section {v}", weight='bold', fontsize=20)
        axt.set_axisbelow(True) 
        # make the ticklines invisible
        axt.tick_params(axis=u'both', which=u'both', length=0)
        axt.legend(loc='upper right')

        for tick in axt.get_xticklabels():
            tick.set_rotation(90)

输出