С учетом того, что заполненные области должны быть нарисованы с использованием пересечений сетки в качестве центральных точек, мы имеем
In [27]: import numpy as np
...: import matplotlib.pyplot as plt
...: np.random.seed(2018)
...: data = np.random.choice([0, 1], size=12).reshape((3, 4))
...: xGrid = np.linspace(1, 4, 4)
...: yGrid = np.linspace(0.1, 0.3, 3)
In [28]: print(data)
[[0 0 0 1]
[1 0 0 0]
[1 1 1 1]]
In [29]: dx, dy = (xGrid[1]-xGrid[0])/2, (yGrid[1]-yGrid[0])/2
In [30]: xli, yli = [], []
...: for y in yGrid:
...: for x in xGrid: # the x's in data are changing faster, so inner loop
...: xli.append([x-dx, x+dx, x+dx, x-dx, x-dx])
...: yli.append([y-dy, y-dy, y+dy, y+dy, y-dy])
In [31]: for xs, ys, Bool in zip(xli, yli, data.flatten()):
...: if Bool : plt.fill(xs, ys, color='red')
...: plt.gca().set_facecolor('yellow')
Выполнение кода выше дает мне 
Стоит отметить, что только закрашенные прямоугольники нарисованы, как показано путем заливки фона области построения другим цветом.
plt.fill
задокументировано здесь и списки, созданные в первом цикле for
, являются просто x , y координатами углов прямоугольника, которые могут быть нарисованы с помощью plt.fill
.
Замечание по эффективности
Если нужно нарисовать несколько сотен прямоугольников, простой подход, описанный выше, будет в порядке, если мы перейдем к десяткам тысяч возможно мы хотим перебрать точки данных с помощью enumerate
, если необходимо построить списки x , y и нарисовать прямоугольник на лету или,еще лучше для производительности, создайте патч Rectangle
, вставьте его вPatchCollection
и использовать метод ax.add_collection
, когда мы завершим цикл на data
- , доступен пример в документации Matplotlib, который можно легко адаптировать к области действия, и другой пример это мой новый ответ.