Постройте гистограмму на разных осях - PullRequest
0 голосов
/ 10 июля 2020

Я читаю файл CSV:

 Notation Level   RFResult   PRIResult   PDResult  Total Result
 AAA       1       1.23        0           2         3.23
 AAA       1       3.4         1           0         4.4
 BBB       2       0.26        1           1.42      2.68
 BBB       2       0.73        1           1.3       3.03
 CCC       3       0.30        0           2.73      3.03
 DDD       4       0.25        1           1.50      2.75
 AAA       5       0.25        1           1.50      2.75
 FFF       6       0.26        1           1.42      2.68
 ...
 ...

Вот код

import pandas as pd
import matplotlib.pyplot as plt

df = pd.rad_csv('home\NewFiles\Files.csv')
Notation = df['Notation']
Level = df['Level']
RFResult = df['RFResult']
PRIResult = df['PRIResult']
PDResult = df['PDResult']

fig, axes = plt.subplots(nrows=7, ncols=1)
ax1, ax2, ax3, ax4, ax5, ax6, ax7 = axes.flatten()
n_bins = 13
ax1.hist(data['Total'], n_bins, histtype='bar') #Current this shows all Total Results in one plot 
plt.show()

Я хочу показать общий результат каждого уровня на каждой отдельной оси, как показано ниже:

ax1 покажет общий результат уровня 1

ax2 покажет общий результат уровня 2

ax3 покажет общий результат уровня 3

ax4 будет показать общий результат уровня 4

ax5 отобразит общий результат уровня 5

ax6 отобразит общий результат уровня 6

ax7 отобразит общий результат уровня 7

1 Ответ

1 голос
/ 10 июля 2020

Вы можете выбрать отфильтрованную часть фрейма данных, просто проиндексировав: df[df['Level'] == level]['Total']. Вы можете l oop через оси, используя for ax in axes.flatten(). Чтобы также получить индекс, используйте for ind, ax in enumerate(axes.flatten()). Обратите внимание, что Python обычно начинает отсчет с 1, поэтому добавление 1 к индексу было бы хорошим выбором для указания уровня.

Обратите внимание, что когда у вас есть обратная косая черта в строке, вы можете избежать их, используя r -string: r'home\NewFiles\Files.csv'.

Значение ylim по умолчанию составляет от 0 до максимальной высоты полосы плюс некоторые отступы. Это можно изменить для каждого ax отдельно. В приведенном ниже примере для демонстрации принципа используется список значений ymax.

ax.grid(True, axis='both) устанавливает сетку для этого ax. Вместо «обоих» можно также использовать «x» или «y», чтобы задать сетку только для этой оси. Линия сетки рисуется для каждого значения тика. (В приведенном ниже примере делается попытка использовать мало места, поэтому видно только несколько линий сетки.)

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

N = 1000
df = pd.DataFrame({'Level': np.random.randint(1, 6, N), 'Total': np.random.uniform(1, 5, N)})

fig, axes = plt.subplots(nrows=5, ncols=1, sharex=True)
ymax_per_level = [27, 29, 28, 26, 27]
for ind, (ax, lev_ymax) in enumerate(zip(axes.flatten(), ymax_per_level)):
    level = ind + 1
    n_bins = 13
    ax.hist(df[df['Level'] == level]['Total'], bins=n_bins, histtype='bar')
    ax.set_ylabel(f'TL={level}') # to add the level in the ylabel
    ax.set_ylim(0, lev_ymax)
    ax.grid(True, axis='both')
plt.show()

resulting plot

PS: A stacked histogram with custom legend could be created as:

import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import pandas as pd
import numpy as np

N = 1000
df = pd.DataFrame({'Level': np.random.randint(1, 6, N),
                   'RFResult': np.random.uniform(1, 5, N),
                   'PRIResult': np.random.uniform(1, 5, N),
                   'PDResult': np.random.uniform(1, 5, N)})
df['Total'] = df['RFResult'] + df['PRIResult'] + df['PDResult']

fig, axes = plt.subplots(nrows=5, ncols=1, sharex=True)
colors = ['crimson', 'limegreen', 'dodgerblue']
column_names = ['RFResult', 'PRIResult', 'PDResult']
for level, ax in enumerate(axes.flatten(), start=1):
    n_bins = 13
    level_data = df[df['Level'] == level][column_names].to_numpy()
    level_mean = level_data.mean()
    ax.hist(level_data, bins=n_bins,
            histtype='bar', stacked=True, color=colors)
    ax.axvline(level_mean, color='gold', ls=':', lw=2)
    ax.set_ylabel(f'TL={level}')  # to add the level in the ylabel
    ax.margins(x=0.01)
    ax.grid(True, axis='both')
legend_handles = [Patch(color=color) for color in colors]
axes[0].legend(legend_handles, column_names, ncol=len(column_names), loc='lower center', bbox_to_anchor=(0.5, 1.02))
plt.show()

гистограмма с накоплением

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