Python гистограмма с накоплением matplotlib - странные результаты - PullRequest
1 голос
/ 26 февраля 2020

Я пытаюсь нанести четыре гистограммы с накоплением на одном графике, используя библиотеку matplotlib Python.

Для каждого наблюдения (obs1, obs2, obs3, obs4) я хочу просмотреть количество каждого компонента (c1, c2, c3, c4, c5, c6), используя гистограмму с накоплением. Это код, который я написал:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = np.array([[-904., 97., 59., 5., 252., 138.], [-603., 65., 0., 29., 0., 0.], [-571., -27., 0., -28., 0., 0.], [-80., 40., 0., -9., 0., 0.]])

data2 = pd.DataFrame(data=data)
data2.index = ['obs1', 'obs2', 'obs3', 'obs4']
data2.columns = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6']

ind = np.arange(4)
width = 0.4

p1 = plt.bar(ind, data2['c1'], width)
p2 = plt.bar(ind, data2['c2'], width)
p3 = plt.bar(ind, data2['c3'], width)
p4 = plt.bar(ind, data2['c4'], width)
p5 = plt.bar(ind, data2['c5'], width)
p6 = plt.bar(ind, data2['c6'], width)

plt.legend((p1[0], p2[0], p3[0], p4[0], p5[0], p6[0]), tuple(data2.columns), bbox_to_anchor = (1.05, 1), loc = 'upper left', borderaxespad = 0.)

Для ясности, это DataFrame (используется для создания графика):

print(data2)
         c1    c2    c3    c4     c5     c6
obs1 -904.0  97.0  59.0   5.0  252.0  138.0
obs2 -603.0  65.0   0.0  29.0    0.0    0.0
obs3 -571.0 -27.0   0.0 -28.0    0.0    0.0
obs4  -80.0  40.0   0.0  -9.0    0.0    0.0

Это график:

enter image description here

Обратите внимание, что график для obs1 находится в точке x = 0, столбец для obs2 - в точке x = 1 и т. Д.

Однако есть две проблемы:

  1. obs1 имеет значение 252 для компонента 5, но высота компонента 5 (фиолетовым цветом) существенно ниже 252. Как это исправить?

  2. obs3 имеет значение -27 для компонента 2, но это вообще не показано на графике. Как я могу решить это?

Спасибо.

1 Ответ

4 голосов
/ 26 февраля 2020

Это потому, что когда вы строите график, ссылка на значение y берется из y=0, таким образом, фиолетовая полоса для компонента 5 obs1 фактически перекрывается с y=0 до y=252, и она блокируется полосой для компонента 6 (нанесено позже) из-за последовательной природы matplotlib строит участки баров.

Похожий компонент obs3 не показан по той же причине.

Чтобы получить то, что вы хотите, столбец с накоплением график, вы можете просто построить с помощью pandas интерфейс построения:

fig, ax = plt.subplots(1,1,figsize=(6,4))

data2.plot(kind='bar', stacked=True, ax=ax)

ax.set_xticklabels(ax.get_xticklabels(), rotation=0)

plt.show()

, который дает вам именно то, что вы хотите:

enter image description here

С другой стороны, я бы предложил построить отдельную гистограмму для каждого компонента, так как они имеют очень разный масштаб, это сделало бы сравнение уровня компонентов по наблюдениям намного более четким:

fig, ax = plt.subplots(1, 6, figsize=(20,4))

for index, col in enumerate(data2.columns):
    data2[col].plot(kind='bar', ax=ax[index], color=f'C{index}', title=f'{col}')
    ax[index].grid(True)
    ax[index].set_xticklabels(ax[index].get_xticklabels(), rotation=0)

plt.show()

, что дает Вы:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...