One idea is to create 4 extra y axes, and set explicit limits for them. All the y-values can be rescaled to be compatible with the host axis.
(The code can still be optimized to make better use of numpy.)
import matplotlib.pyplot as plt
import numpy as np
fig, host = plt.subplots()
N = 20
y1 = np.random.uniform(10, 50, N)
y2 = np.sin(np.random.uniform(0, np.pi, N))
y3 = np.random.binomial(300, 0.9, N)
y4 = np.random.pareto(10, N)
y5 = np.random.uniform(0, 800, N)
ys = [y1, y2, y3, y4, y5]
y0min = ys[0].min()
dy = ys[0].max() - y0min
zs = [ys[0]] + [(y - y.min()) / (y.max() - y.min()) * dy + y0min for y in ys[1:]]
ynames = ['P1', 'P2', 'P3', 'P4', 'P5']
axes = [host] + [host.twinx() for i in range(len(ys) - 1)]
for i, (ax, y) in enumerate(zip(axes, ys)):
ax.set_ylim(y.min(), y.max())
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)
if ax != host:
ax.spines['left'].set_visible(False)
ax.yaxis.set_ticks_position('right')
ax.spines["right"].set_position(("axes", i / (len(ys) - 1)))
host.set_xlim(0, len(ys) - 1)
host.set_xticks(range(len(ys)))
host.set_xticklabels(ynames)
host.tick_params(axis='x', which='major', pad=7)
host.spines['right'].set_visible(False)
colors = plt.cm.tab20.colors
for j in range(len(ys[0])):
host.plot(range(len(ys)), [z[j] for z in zs], c=colors[j % len(colors)])
plt.show()
