我正在尝试在matplotlib中实现水平图表(请参见:http://square.github.com/cubism/)。
基本思路是将时间序列以较小的宽高比显示,并且随着值的增加(超过y轴限制),它们会以较暗的颜色从底部重新开始(想象一下旧的Atari游戏,当你超过屏幕顶部时,会从底部弹出)。
我的基本方法是将y数据分成块,并使用
对于仅具有正或负数据,这似乎运作良好。
正数:
基本思路是将时间序列以较小的宽高比显示,并且随着值的增加(超过y轴限制),它们会以较暗的颜色从底部重新开始(想象一下旧的Atari游戏,当你超过屏幕顶部时,会从底部弹出)。
我的基本方法是将y数据分成块,并使用
ax.twinx()
在新的轴上绘制每个垂直组,并适当设置限制。对于仅具有正或负数据,这似乎运作良好。
正数:
负面:
但出于某些原因,两者一起做就会出问题:
# setup the environment
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, np.pi*4, 137)
y = (2*np.random.normal(size=137) + x**2)
# reflect everything around the origin
xx = np.hstack([-1*x[::-1], x])
yy = np.hstack([-1*y[::-1], y])
# function to do the plot
def horizonPlot(ax, x, y, nfolds=3, inverty=False, color='CornflowerBlue'):
axes = [ax]
if inverty:
ylims = np.linspace(y.min(), y.max(), nfolds + 1)[::-1]
else:
ylims = np.linspace(y.min(), y.max(), nfolds + 1)
for n in range(1, nfolds):
newax = axes[-1].twinx()
axes.append(newax)
for n, ax in enumerate(axes):
ax.fill_between(x, y, y2=ylims[n], facecolor=color, alpha=1.0/nfolds, zorder=n)
ax.set_ylim([ylims[n], ylims[n+1]])
ax.set_yticklabels([])
ax.set_yticks([])
if inverty:
ax.invert_yaxis()
ax.set_xlim([x.min(), x.max()])
return fig
fig, baseax = plt.subplots(figsize=(6.5,1.5))
posax = baseax.twinx()
negax = posax.twinx()
fig = horizonPlot(posax, xx, np.ma.masked_less(yy, 0), inverty=False, color='DarkGreen')
fig = horizonPlot(negax, xx, np.ma.masked_greater(yy, 0), inverty=True, color='CornflowerBlue')
for ax in fig.get_axes():
ax.set_yticklabels([])
fig.tight_layout()
plt.show()
糟糕的图表(注意正面缺乏多个层次):
zstart
参数是什么作用?当我在自己的电脑上运行时,图表看起来甚至更糟,最高层绘制在图表的外面并抛出了tight_layout: falling back to Agg renderer
的错误提示。 - Milla Well