I'm using matplotlib.gridspec to create a grid for 3 axes.
My current code looks like:
from matplotlib import pyplot as plt
from matplotlib.gridspec import GridSpec
import pandas as pd
df = pd.DataFrame({'d1': [20,30,40], 'd2': [10,20,30]}, index=['a', 'b', 'c']) # Dataset to emulate real data structure
df = df.apply(lambda l: l / l.sum() * 100).T
df.index = ['Some dataset', 'Some dataset 2']
fig = plt.figure(figsize=(6.25, 4.0))
gs = GridSpec(3, 2, figure=fig)
ax1 = fig.add_subplot(gs[:2, 0])
ax2 = fig.add_subplot(gs[:2, 1])
hbar_ax = fig.add_subplot(gs[2, :])
df.plot(ax=hbar_ax, kind='barh', stacked=True, width=0.5, color=['#FF3B3B', '#F4B083', '#9CD5A4'], legend=None)
hbar_ax.invert_yaxis()
hbar_ax.set_xlim(-1, 101)
for n in df:
for i, (cs, ab, pc) in enumerate(zip(df.iloc[:, 0:].cumsum(1)[n],
df[n], df[n])):
hbar_ax.text(cs - ab / 2, i, str(np.round(pc, 1)) + '%',
va = 'center', ha = 'center', fontsize='medium')
hbar_ax.tick_params(axis='both', which='both', length=0)
hbar_ax.tick_params(
axis='x',
which='both',
bottom=False,
top=False,
labelbottom=False)
plt.tight_layout()
Which produces this figure:
But i cant figure out how to adjust the top plots to space out to look like this:
You can use subfigures:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.gridspec import GridSpec
import pandas as pd
df = pd.DataFrame({'d1': [20,30,40], 'd2': [10,20,30]}, index=['a', 'b', 'c']) # Dataset to emulate real data structure
df = df.apply(lambda l: l / l.sum() * 100).T
df.index = ['Some dataset', 'Some dataset 2']
# create subplot grid (using wpace to set space between top two plots)
fig, axs = plt.subplots(3, 2, layout="constrained", figsize=(6.25, 4.0), gridspec_kw={"wspace": 0.2})
gridspec = axs[0, 0].get_subplotspec().get_gridspec()
# add in top two plots (first removing existing axes)
for ax in axs[:2, 0]:
ax.remove()
for ax in axs[:2, 1]:
ax.remove()
ax1 = fig.add_subplot(gridspec[:2, 0])
ax2 = fig.add_subplot(gridspec[:2, 1])
# create subfigure for bottom plot
for ax in axs[2, :]:
ax.remove()
subfig = fig.add_subfigure(gridspec[2, :])
# bottom axis
hbar_ax = subfig.subplots(1)
df.plot(ax=hbar_ax, kind='barh', stacked=True, width=0.5, color=['#FF3B3B', '#F4B083', '#9CD5A4'], legend=None)
hbar_ax.invert_yaxis()
hbar_ax.set_xlim(-1, 101)
for n in df:
for i, (cs, ab, pc) in enumerate(zip(df.iloc[:, 0:].cumsum(1)[n],
df[n], df[n])):
hbar_ax.text(cs - ab / 2, i, str(np.round(pc, 1)) + '%',
va = 'center', ha = 'center', fontsize='medium')
hbar_ax.tick_params(axis='both', which='both', length=0)
hbar_ax.tick_params(
axis='x',
which='both',
bottom=False,
top=False,
labelbottom=False)
fig.show()
This gives: