A matplotlib.patches.PathPatch
имеет один цвет лица.Его нельзя по-разному раскрасить.Это упоминается в , например,
может более эффективно рисовать коллекции объектов правильной формы с однородными свойствами с помощью PathCollection.
Таким образом, мотивация использовать эту стратегию вместо создания обычной гистограммы и раскрасить ее столбцы - это эффективность.Немного менее эффективный способ создания гистограммы, но все же быстрее, чем обычный bars
, - это использование PolyCollection
.
Итак, давайте рассмотрим три различных решения ниже.
import numpy as np; np.random.seed(19680801)
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.path as path
import matplotlib.collections
import matplotlib.cm
data = np.random.randn(1000)
def compoundpathhist(data, nbins=50):
n, bins = np.histogram(data, nbins)
# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n
# we need a (numrects x numsides x 2) numpy array for the path helper
# function to build a compound path
XY = np.array([[left, left, right, right], [bottom, top, top, bottom]]).T
# get the Path object
barpath = path.Path.make_compound_path_from_polys(XY)
# make a patch out of it
patch = patches.PathPatch(barpath)
fig, ax = plt.subplots()
ax.add_patch(patch)
# update the view limits
ax.set_xlim(left[0], right[-1])
ax.set_ylim(bottom.min(), top.max())
fig.savefig("bartest.png")
def polyhist(data, nbins=50, colors=True):
n, bins = np.histogram(data, nbins)
# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n
# we need a (numrects x numsides x 2) numpy array to be used as
# vertices for the PolyCollection
XY = np.array([[left, left, right, right], [bottom, top, top, bottom]]).T
c=None
if colors:
c = matplotlib.cm.RdYlBu(n/n.max())
pc = matplotlib.collections.PolyCollection(XY, facecolors=c)
fig, ax = plt.subplots()
ax.add_collection(pc)
# update the view limits
ax.set_xlim(left[0], right[-1])
ax.set_ylim(bottom.min(), top.max())
fig.savefig("bartest.png")
def hist_c(data, nbins=50, colors=True):
fig, ax = plt.subplots()
n, bins, patches = ax.hist(data, nbins)
if colors:
cols = matplotlib.cm.RdYlBu(n/n.max())
for p,c in zip(patches, cols):
p.set_facecolor(c)
# update the view limits
ax.set_xlim(bins.min(), bins.max())
ax.set_ylim(n.min(), n.max())
fig.savefig("bartest.png")
compoundpathhist(data, nbins=50)
polyhist(data, nbins=50)
hist_c(data, nbins=50, colors=True)
plt.show()

- Первый (
compoundpathhist
) - тот из связанного примера.Это быстро, но не может показать цвет. - Второй (
polyhist
) не использует ни одного патча, а вместо него PolyCollection
.Цвет лица PolyCollection
можно установить с помощью карты цветов. - Третье (
hist_c
) - это адаптированное обычное решение для раскрашивания отдельных полос.
Теперь мы можем синхронизировать три функции.Я использую 90000 точек данных и 50, 500 и 5000 бинов.

Мы наблюдаем, что для обычного числа бинов ~ 50, по существу, нет никакой разницы между этими методами.Однако для большего количества ячеек метод hist
занимает значительно больше времени.Даже для 5000 бинов почти нет разницы между методом compoundpathhist
(который не может использовать цвет) и polyhist
, который может использовать цвет.Следовательно, это полезная альтернатива без ущерба для эффективности.Между прочим, почти нет разницы между использованием цвета или не использованием цвета в соответствующих функциях.