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)
输出
我有以下 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)
输出