import numpy as np
import matplotlib.pyplot as plt
def makeLayer(y, height):
neg=0.0
pos=0.0
if y > 0:
if y - height >= 0:
pos = height
y -= pos
else:
pos = y
elif y < 0:
if y + height <= 0:
neg = height
y += neg
else:
neg = -y
return pos, neg
def horizonPlot(x, y, nfolds=3, negcolor='CornflowerBlue', poscolor='DarkGreen', **figkwargs):
fig, ax = plt.subplots(**figkwargs)
alpha = 1.0/nfolds
vlayer = np.vectorize(makeLayer)
height = np.ceil(np.abs(y).max()/nfolds)
while (y != 0).any():
layer = vlayer(y,height)
y -= layer[0];
y += layer[1]
ax.fill_between(x, 0, layer[0], color=poscolor, alpha=alpha)
ax.fill_between(x, height-layer[1], height, color=negcolor, alpha=alpha)
ax.set_yticks([])
ax.set_xlim([x.min(), x.max()])
ax.set_ylim([0, height])
ax.xaxis.grid(False)
ax.yaxis.grid(False)
return fig
# data
x = np.linspace(0, np.pi*4, 137)
y = (2*np.random.normal(size=137) + x**2)
xx = np.hstack([-1*x[::-1], x])
yy = np.hstack([-1*y[::-1], y])
# figure properties
figkwargs = dict(figsize=(12,2), dpi=300)
Overall, everything looks pretty smooth
fig, ax = plt.subplots(**figkwargs)
pos = np.ma.masked_less(yy, 0)
neg = np.ma.masked_greater(yy, 0)
ax.fill_between(xx, neg, y2=0, color='CornflowerBlue', alpha=0.5)
ax.fill_between(xx, pos, y2=0, color='DarkGreen', alpha=0.5)
ax.xaxis.grid(False)
ax.yaxis.grid(False)
ax.set_xlim([xx.min(), xx.max()])
ax.set_ylim([neg.min(), pos.max()])
ax.set_yticks([])
[]
Notice how the variablitily of the data is much more apparent
fig = horizonPlot(xx, yy, nfolds=3, **figkwargs)