Python Matplotlib - fill_between删除yaxis顶部行之间的空格

时间:2017-06-14 17:59:42

标签: python matplotlib

当我使用fill_between时,彩色贴片垂直方向略微倾斜,因此y轴顶部有白色空间,而y轴底部的颜色很好地合并。任何人都知道如何防止这种情况/了解导致这种情况的原因是什么?enter image description here

该图显示“天气窗口”:当天气参数低于某个阈值时,该时间段是“可操作的”,而在其他时间它是“不可操作的”。生成此图的代码是:

figure = plt.figure(figsize=(8, 3 * 3))
gs = gridspec.GridSpec(3, 1)
gs.update(hspace=0.3)
ax0 = plt.subplot(gs[0])
df1.plot() # pandas DataSeries
ax0.set_xlabel('')
ax1 = plt.subplot(gs[1])
df2.plot() # pandas DataSeries
ax1.set_xlabel('')
ax2 = plt.subplot(gs[2])
trans = mtransforms.blended_transform_factory(ax2.transData, ax2.transAxes)
ax2.plot(xtime, y, color = 'green', alpha = 0.5, lw = 0.01)
ax2.set_xlim(xtime[0], xtime[-1])
ax2.fill_between(xtime2, 0, 1, where = yop > 0, facecolor = 'green', alpha = 0.5, interpolate = True, transform = trans)
# yop is numpy array of 0's and 1's
ax2.fill_between(xtime2, 0, 1, where = ynonop > 0, facecolor = 'red', alpha = 0.5, interpolate = True, transform = trans)
# ynonop has 0's and 1's opposite to yop

interpolate = True扮演的角色是消除点之间的空白区域。

以下是测试问题的简单代码:

import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.arange(0.0, 365, 1)
yop = np.random.randint(2, size=len(x))
ynonop = np.copy(yop)
# make 0's and 1's opposite to yop
ynonop[ynonop == 1] = 2
ynonop[ynonop == 0] = 1
ynonop[ynonop == 2] = 0
import matplotlib.transforms as mtransforms
trans = mtransforms.blended_transform_factory(ax.transData, ax.transAxes)
ax.set_xlim(x[0], x[-1])
ax.fill_between(x, 0, 1, where=yop > 0, facecolor='green', alpha=0.5, interpolate = True, transform=trans)
ax.fill_between(x, 0, 1, where=ynonop > theta, facecolor='red', alpha=0.5, interpolate = True, transform=trans)
plt.show()
# plt.savefig('test.png', bbox_inches = 0)

enter image description here

2 个答案:

答案 0 :(得分:2)

要了解导致白色条纹的原因,您可以放大图。

enter image description here

因为fill_between在满足特定条件的点之间填充,所以你会得到一个类似锯齿的形状。

可能的解决方案可能是使用broken_barh图。为此,需要将数据重新排列为(位置,宽度)的2列格式。

import matplotlib.pyplot as plt
import numpy as np

fig, (ax,ax2) = plt.subplots(nrows=2, sharex=True, sharey=True)

x = np.arange(0.0, 365, 1)
yop = np.random.randint(2, size=len(x))
ynonop = np.copy(yop)
# make 0's and 1's opposite to yop
ynonop[ynonop == 1] = 2
ynonop[ynonop == 0] = 1
ynonop[ynonop == 2] = 0

trans = ax.get_xaxis_transform() 
ax.set_xlim(x[0], x[-1])
ax.fill_between(x, 0, 1, where=yop > 0, facecolor='green', 
                alpha=0.5, interpolate = True, transform=trans)
ax.fill_between(x, 0, 1, where=ynonop > 0, facecolor='red', 
                alpha=0.5, interpolate = True, transform=trans)

trans2 = ax2.get_xaxis_transform()
xra = np.c_[x[:-1],np.diff(x)]
ax2.broken_barh(xra[yop[:-1] > 0,:], (0,1), 
                      facecolors='green', alpha=0.5, transform=trans2)

ax2.broken_barh(xra[ynonop[:-1] > 0,:], (0,1), 
                      facecolors='red', alpha=0.5, transform=trans2)  

ax.set_title("fill_between")
ax2.set_title("broken_barh")
plt.show()

enter image description here

答案 1 :(得分:1)

您也可以使用imshow

执行此操作
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as mcolors
import matplotlib.transforms as mtransforms

fig, ax = plt.subplots()
x = np.arange(0.0, 365, 1)
yop = np.random.randint(2, size=len(x))

trans = mtransforms.blended_transform_factory(ax.transData, ax.transAxes)
ax.set_xlim(x[0], x[-1])
lc = mcolors.ListedColormap(['r', 'g'], name='RWG')
ax.imshow(yop.reshape(1, -1),
          extent=[0, len(yop), 0, 1],
          transform=trans,
          cmap=lc,
          norm=mcolors.NoNorm(), alpha=.5)

ax.set_aspect('auto')
# debugging plotting
ax.step(x, yop, '.', where='post', linestyle='none')
ax.set_ylim([-.1, 1.1])
plt.show()

enter image description here

通过调整extent中的x值,您可以精确控制像素在数据空间中的位置。