В matplotlib, как нарисовать гистограмму нескольких наборов данных, чтобы поместить самые маленькие столбцы вперед? - PullRequest
1 голос
/ 03 февраля 2010

Я хочу поместить несколько наборов данных на гистограмму и не допускать, чтобы меньшие столбцы были скрыты большими, и я не хочу их компенсировать.Например,

bar (0, 1.)

bar (0, 2.)

показывает только второй бар высотой 2.0, первый бар скрыт,Есть ли способ заставить matplotlib рисовать бары с самыми маленькими сверху?NB Я не хочу, чтобы гистограмма с накоплением или смещение столбцов в x-направлениях.

Я могу упорядочить все данные из всех наборов данных по высоте столбца и нанести каждый столбец отдельно в этом порядке, но я бы предпочел наносить каждый столбец отдельно, а не каждый набор данных по очереди. Кто-нибудь знает способделать это?

Большое спасибо

Ответы [ 3 ]

4 голосов
/ 07 января 2012

Я знаю, что это старый вопрос, но я натолкнулся на него для своих собственных целей, и, поскольку мне казалось, что это будет чем-то, что я буду делать снова и снова, я собрал обертку для функции Хисто (это то, что я буду использовать; модификация bar должна быть тривиальной):

from matplotlib import pyplot as mpl
from numpy import argsort, linspace

def hist_sorted(*args, **kwargs):
    all_ns = []
    all_patches = []

    labels = kwargs.pop('labels', None)
    if not labels:
        labels = ['data %d' % (i+1) for i in range(len(args))]
    elif len(labels) != len(args):
        raise ValueError('length of labels not equal to length of data')

    bins = kwargs.pop('bins', linspace(min(min(a) for a in args),
                                       max(max(a) for a in args),
                                       num = 11))

    for data, label in zip(args, labels):
        ns, bins, patches = mpl.hist(data, bins=bins, label=label, **kwargs)
        all_ns.append(ns)
        all_patches.append(patches)
    z_orders = -argsort(all_ns, axis=0)

    for zrow, patchrow in zip(z_orders, all_patches):
        assert len(zrow) == len(patchrow)
        for z_val, patch in zip(zrow, patchrow): 
            patch.set_zorder(z_val)

    return all_ns, bins, all_patches

Это принимает наборы данных в качестве анонимных аргументов и любые метки в качестве аргументов ключевых слов (для легенды), а также любой другой аргумент ключевого слова, который можно использовать с hist.

3 голосов
/ 03 февраля 2010

Метод bar возвращает объект matplotlib.patches.Rectangle. У объекта есть метод set_zorder. Установка zorder первого выше второго поместит его сверху.

Вы можете "легко" упорядочить z-порядок элементов, проверив, имеют ли они одинаковый x, и упорядочив их по высоте.

from matplotlib import pylab
pylab.bar([0, 1], [1.0, 2.0])
pylab.bar([0, 1], [2.0, 1.0])

# loop through all patch objects and collect ones at same x
all_patches = pylab.axes().patches
patch_at_x = {}
for patch in all_patches:
    if patch.get_x() not in patch_at_x: patch_at_x[patch.get_x()] = []
    patch_at_x[patch.get_x()].append(patch)

# custom sort function, in reverse order of height
def yHeightSort(i,j):
    if j.get_height() > i.get_height(): return 1
    else: return -1

# loop through sort assign z-order based on sort
for x_pos, patches in patch_at_x.iteritems():
    if len(patches) == 1: continue
    patches.sort(cmp=yHeightSort)
    [patch.set_zorder(patches.index(patch)) for patch in patches]

pylab.show()

альтернативный текст http://img697.imageshack.us/img697/8381/tmpp.png

1 голос
/ 03 февраля 2010

Оригинал:

>>> from matplotlib import pylab
>>> data1 = [0.3, 0.9, 0.1]
>>> data2 = [3.0, 0.2, 0.5]
>>> colors = ['b','magenta','cyan']
>>> data_list = [data1,data2]
>>> num_bars = len(data_list)
>>> for i, d in enumerate(data_list):
...     for j,value in enumerate(sorted(d,reverse=True)):
...         c = colors[j]
...         obj_list = pylab.bar(i*0.4,value,width=0.8/num_bars,color=c)
... 

Вы можете нарисовать их по порядку, например, или сделать zorder

Edit:

Я немного обострил это. По сути, ключ заключается в сортировке данных для каждого бара от наибольшего к наименьшему до вызова бара. Но вы можете вернуться позже и выполнить set_zorder и т. Д. Фактически я сохраняю объекты, возвращенные из bar (), на тот случай, если вы захотите их проверить.

import numpy as np
from pylab import *

data = [[6.7, 1.5, 4.5], [2.0, 3.25, 5.7]]
w = 0.5
xlocations =  np.array(range(len(data)))+w
colors = ['r','b','cyan']

oL = list()
for x,d in zip(xlocations, data):
    for c,value in zip(colors, sorted(d,reverse=True)):
        b = bar(x, value, width=w, color=c)
        oL.extend(b)
show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...