Гистограмма с накоплением с разным порядком цветов с использованием matplotlib

Я новичок в питоне. Я пытаюсь сделать горизонтальную гистограмму с другим порядком цветов.

У меня есть набор данных, подобный приведенному ниже:

dataset = [{'A':19, 'B':39, 'C':61, 'D':70},
           {'A':34, 'B':68, 'C':32, 'D':38},
           {'A':35, 'B':45, 'C':66, 'D':50},
           {'A':23, 'B':23, 'C':21, 'D':16}]
data_orders = [['A', 'B', 'C', 'D'], 
               ['B', 'A', 'C', 'D'], 
               ['A', 'B', 'D', 'C'], 
               ['B', 'A', 'C', 'D']]

Первый список содержит числовые данные, а второй - порядок каждого элемента данных. Мне нужен второй список здесь, потому что порядок A, B, C и D имеет решающее значение для набора данных при их представлении в моем случае.

Используя данные, подобные приведенным выше, я хочу создать столбчатую диаграмму с накоплением, как на картинке ниже. Это было сделано мной вручную в MS Excel. Что я надеюсь сделать сейчас, так это сделать этот тип гистограммы с использованием Matplotlib с набором данных, подобным приведенному выше, более автоматическим способом. Я также хочу добавить легенду к диаграмме, если это возможно.

Гистограмма с накоплением и разным порядком цветов (пример)

На самом деле, я совершенно заблудился, пытаясь это сделать самостоятельно. Любая помощь будет очень и очень полезной. Спасибо вам большое за ваше внимание!


person miyazaki_tara    schedule 30.06.2012    source источник
comment
взгляните на этот matplotlib.sourceforge.net/mpl_examples/pylab_examples/   -  person Ashwini Chaudhary    schedule 30.06.2012
comment
Уважаемый Ашвини, Спасибо за эту информацию. Это пример, приведенный на странице Matplotlib? Я использовал эту модель как учебник, но проблема заключалась в том, что мне казалось, что я не в силах применить эту модель к моей реальной цели. Вот почему я разместил свой вопрос! Но ваше предложение о перечислении было бы для меня подсказкой. Большое спасибо!   -  person miyazaki_tara    schedule 30.06.2012


Ответы (2)


Это длинная программа, но она работает, я добавил одни фиктивные данные, чтобы различать количество строк и количество столбцов:

import numpy as np
from matplotlib import pyplot as plt

dataset = [{'A':19, 'B':39, 'C':61, 'D':70},
           {'A':34, 'B':68, 'C':32, 'D':38},
           {'A':35, 'B':45, 'C':66, 'D':50},
           {'A':23, 'B':23, 'C':21, 'D':16},
           {'A':35, 'B':45, 'C':66, 'D':50}]
data_orders = [['A', 'B', 'C', 'D'], 
               ['B', 'A', 'C', 'D'], 
               ['A', 'B', 'D', 'C'], 
               ['B', 'A', 'C', 'D'],
               ['A', 'B', 'C', 'D']]
colors = ["r","g","b","y"]
names = sorted(dataset[0].keys())
values = np.array([[data[name] for name in order] for data,order in zip(dataset, data_orders)])
lefts = np.insert(np.cumsum(values, axis=1),0,0, axis=1)[:, :-1]
orders = np.array(data_orders)
bottoms = np.arange(len(data_orders))

for name, color in zip(names, colors):
    idx = np.where(orders == name)
    value = values[idx]
    left = lefts[idx]
    plt.bar(left=left, height=0.8, width=value, bottom=bottoms, 
            color=color, orientation="horizontal", label=name)
plt.yticks(bottoms+0.4, ["data %d" % (t+1) for t in bottoms])
plt.legend(loc="best", bbox_to_anchor=(1.0, 1.00))
plt.subplots_adjust(right=0.85)
plt.show()

итоговая цифра:

введите описание изображения здесь

person HYRY    schedule 30.06.2012
comment
Большое спасибо за ваше время на все это. Это очень полезно !! Я многое почерпнул из ваших сценариев. - person miyazaki_tara; 30.06.2012
comment
Небольшое улучшение - использовать barh - person guhur; 24.03.2018

person    schedule
comment
Уважаемый Ашвини, Спасибо, что уделили время, чтобы ответить на мой вопрос. Я постараюсь изо всех сил выяснить, как это можно использовать для решения моей проблемы! - person miyazaki_tara; 30.06.2012
comment
@miyazaki_tara другим способом может быть создание нового списка списков, в котором данные уже упорядочены согласно data_orders. - person Ashwini Chaudhary; 30.06.2012
comment
@miyazaki_tara [[dataset[i][y] for y in data_orders[i]] for i in range(len(data_orders))] вернет [[19, 39, 61, 70], [68, 34, 32, 38], [35, 45, 50, 66], [23, 23, 21, 16]] - person Ashwini Chaudhary; 30.06.2012
comment
Проблема заключалась в том, что я не понимал, как работает matplotlib, но, вероятно, я получил это благодаря вашей помощи! Спасибо! - person miyazaki_tara; 30.06.2012