Как нарисовать 100% сложенные столбцы со смешанными значениями +ve и -ve в matplotlib?

У меня есть некоторые данные со смешанными положительными и отрицательными значениями, сумма абсолютных значений каждой переменной = 100% Вот некоторые примеры данных:

Out01 = [79.069,-1.602,5.067,-4.241,-5.433,-4.590]
Out02 = [50.348,13.944,-15.373,6.554,5.541,8.240]
Out03 = [-8.053,0.819,-9.741,2.814,22.475,56.098]
Out04 = [-17.350,33.710,-18.510,-0.842,3.050,26.537]
Out05 = [-20.169,37.583,-20.785,-2.041,1.728,17.695]

Я нарисовал их по желанию в Microsoft Excel следующим образом по диаграмме «100% столбцов с накоплением»: Я нарисовал их по желанию в Microsoft Excel следующим образом по диаграмме столбцов со 100% накоплением: Теперь я хочу нарисуйте аналогичную диаграмму на питоне через библиотеку matplotlib.

Как я могу это сделать?


person Mohammad ElNesr    schedule 21.04.2016    source источник
comment
Здесь приведен пример столбца с накоплением из галереи matplotlib. Должен дать вам хорошую отправную точку.   -  person Primer    schedule 21.04.2016
comment
Проблема в этом примере в том, что он работает только с положительными данными. Пожалуйста, прочитайте описание в первом ответе ниже.   -  person Mohammad ElNesr    schedule 21.04.2016
comment
Кажется, это повторяющийся вопрос: stackoverflow.com/questions/35979852/   -  person elke    schedule 11.08.2016


Ответы (1)


Наконец, я получил ответ. Когда я следовал примеру на странице matplotlib, он включает ключевое слово bottom, указывающее рост данных каждой выборки по сравнению с предыдущей.

p2 = plt.bar(ind, womenMeans, width, color='y', bottom=menMeans, yerr=womenStd)

Например, если мы хотим отобразить данные о мужчинах и женщинах, как в примере, мы начинаем с мужчин с оценкой 20 (в серии G1), затем, чтобы нарисовать женщин, они начинают отображать значение 25 с внизу значение 20. Чтобы расширить это, если мы добавили другую категорию, скажем, детей, с оценкой 15, то она должна быть построена с bottom = 20 + 25 = 45 и т. д.

Проблема с отрицательными значениями заключается в том, что они росли в направлении, противоположном положительным. поэтому он должен начинаться с основания = 0, затем с максимального значения суммы либо положительных, либо отрицательных значений независимо друг от друга. Чтобы понять это на примере, если мы хотим построить ряд следующим образом: (20, 25, -15, 30, -10, -5, 17, 3, -28) Основания каждого значения должны быть следующими (0, 20, 0, 45, -15, -25, 75, 92, -30) Почему?

Для 20 мы просто начинаем рисовать, поэтому дно не требуется. Для числа 25 нам нужно увеличить его на 20. Для числа -15 это первое отрицательное значение, поэтому оно должно быть нарисовано ниже оси без нижнего значения, поэтому нижнее значение = 0. Для числа 30 оно должно быть увеличено на 20 + 25 = 45 Для -10 оно должно начинаться ниже предыдущего отрицательного значения, равного -15. Для следующего -5 оно должно начинаться ниже -10 + -15 = -25 И так далее...

def bottoms_matrix(matrix):
    positives = []
    negatives = []
    for i, row_mat in enumerate(matrix):
        tmp_p = []
        tmp_n = []
        for j, cell in enumerate(row_mat):
            if cell >0:
                tmp_p.append(cell)
                tmp_n.append(0.)
            else:
                tmp_p.append(0.)
                tmp_n.append(cell)
        positives.append(tmp_p)
        negatives.append(tmp_n)

    # get cumulative sums
    positives = positives[:-1]
    negatives = negatives[:-1]
    positives.insert(0, [0.] * len (matrix[0]))
    negatives.insert(0, [0.] * len(matrix[0]))
    tmp = swap_matrix(positives)
    tmp = [list(np.cumsum(t)) for t in tmp]
    positives = swap_matrix(tmp)

    tmp = swap_matrix(negatives)
    tmp = [list(np.cumsum(t)) for t in tmp]
    negatives = swap_matrix(tmp)

    final_matrix =[]
    for i, row_mat in enumerate(matrix):
        tmp =[]
        for j, cell in enumerate(row_mat):
            tmp.append(positives[i][j] if cell > 0 else negatives[i][j])
        final_matrix.append(tmp)
    return final_matrix

Полный пример с данными и всеми вспомогательными функциями загружен на мою страницу Git< /а>.

person Mohammad ElNesr    schedule 21.04.2016
comment
Я ждал 3 дня, но, к сожалению, никто не ответил. Однако я знал ответ и поместил его здесь для пользы других. Я отметил, что это принято для уверенности других, что это действительно работает, хотя я не заработал за это репутацию. - person Mohammad ElNesr; 25.04.2016
comment
Ссылка на вашу страницу Git не работает. Можно ли добавить сюда полный пример + график? - person elke; 11.08.2016
comment
Спасибо @elke за ваше замечание. Я исправил битую ссылку. - person Mohammad ElNesr; 24.08.2016
comment
Я получаю «индекс списка вне диапазона» из вашей функции транспонирования swap_array() в python 3 - person Carl; 31.01.2019
comment
Спасибо, @Carl, за заботу. Вы можете использовать np.transpose(positives) вместо swap_matrix(positives). это будет быстрее и проще. Я опубликовал это решение до изучения numpy, поэтому я сам реализовал функцию транспонирования. - person Mohammad ElNesr; 31.01.2019
comment
Спасибо за ваш ответ. Я пробовал что-то подобное, но у меня были другие насущные проблемы. Я хотел бы вернуться к этому: обновили ли вы свой репозиторий github для лучшего решения? с уважением. - person Carl; 31.01.2019
comment
Пока нет @Carl, так как сейчас я слишком занят другими делами. - person Mohammad ElNesr; 31.01.2019