Наложение трех гистограмм на одном графике - PullRequest
1 голос
/ 24 сентября 2019

Я пытаюсь построить что-то подобное, используя данные из Pandas DataFrame.Дата - это числа от 0 до 100, представляющие проценты.У меня есть 3 столбца, представляющих 3 разные категории с процентными значениями для каждого.

Что я хотел бы получить:

perfect hist example

Что яполучить с помощью этого кода:

df_margins = pd.read_excel("path to excel file")
df_margins.reset_index(drop=True, inplace=True)
df_margins_sort = pd.DataFrame(np.sort(df_margins.values, axis=0), index=df_margins.index, columns=df_margins.columns)
df_margins_sort.hist( alpha=0.5)

result 1

Попытка с библиотекой seaborn Я получаю это:

x = df_margins_sort["safety_margin_distribution_0"].tolist()
y = df_margins_sort["safety_margin_distribution_5"].tolist()
z = df_margins_sort["safety_margin_distribution_10"].tolist()
ggg = [x,y,z]
fig, ax = plt.subplots()
for a in ggg:
    sns.distplot(a, bins=range(1, 100, 10), ax=ax, kde=False)
ax.set_xlim([0, 100])

seaborn results

Скриншот моих данных, которые я пытаюсь построить: data example

79.6657 8.3008  12.0334
28  72  0       
51.4077 48.5923 0
84.1176 2.7451  13.1373
79.5455 1.0101  19.4444
51.9205 48.0795 0
57.2877 6.5906  36.1217
71.2589 11.4014 17.3397
56.2624 43.7376 0
76.4228 0   23.5772
51.8473 6.6502  41.5025
74.8555 25.1445 0
85.8254 14.1746 0
63.2754 0.7444  35.9801

Ответы [ 3 ]

2 голосов
/ 24 сентября 2019

Вы можете попробовать вывести индивидуальную историю на одну и ту же ось:

np.random.seed(1)
df = pd.DataFrame(np.random.randint(0,10,(100,3)), columns=list('abc'))

fig, ax = plt.subplots()

for col in df.columns:
    df[col].hist(alpha=0.3, ax=ax, label=col)

ax.legend()

Вывод, который, кстати, выглядит как ваш вывод морского происхождения:

enter image description here

1 голос
/ 24 сентября 2019

Использование seaborn:

Ваши данные:

 safety_margin_distribution_5  safety_margin_distribution_10  safety_margin_distribution_0
                      79.6657                         8.3008                       12.0334
                      28.0000                        72.0000                        0.0000
                      51.4077                        48.5923                        0.0000
                      84.1176                         2.7451                       13.1373
                      79.5455                         1.0101                       19.4444
                      51.9205                        48.0795                        0.0000
                      57.2877                         6.5906                       36.1217
                      71.2589                        11.4014                       17.3397
                      56.2624                        43.7376                        0.0000
                      76.4228                         0.0000                       23.5772
                      51.8473                         6.6502                       41.5025
                      74.8555                        25.1445                        0.0000
                      85.8254                        14.1746                        0.0000
                      63.2754                         0.7444                       35.9801

Код

  • seaborn.distplot
  • Ключевая проблема при первоначальной попытке с использованием seaborn, не обеспечивала label и не вызывал plt.legend()
  • Нет необходимости создавать отдельный объект для каждого столбца, как это сделано с [x, y, z]
import seaborn as sns
import pandas as pd
import matplotlib.pyplt as plt

plt.figure(figsize=(7, 6))
for col in df.columns:
    sns.distplot(df[col], label=col,
                 bins=range(0, 101, 10),
                 kde=False, hist_kws=dict(edgecolor='black'))

plt.xlabel('Value Range')
plt.ylabel('Frequency')
plt.legend()
plt.xticks(range(0, 101, 10))
plt.show()

enter image description here

  • Параметр bins distplot устанавливает корзинуразмеры, но для применения меток на отметках, используйте plt.xticks
0 голосов
/ 25 сентября 2019

Я хотел бы предложить другой подход.Он не избегает морского происхождения, но он избегает петель.

Рабочий процесс налицо: считайте данные, преобразуйте в аккуратный (длинный) формат, а затем сопоставьте гистограмму с сеткой морского борова:

из io import StringIO import pandas import seaborn

seaborn.set (style = 'ticks')

data = StringIO("""\
safety_margin_distribution_5  safety_margin_distribution_10  safety_margin_distribution_0
                      79.6657                         8.3008                       12.0334
                      28.0000                        72.0000                        0.0000
                      51.4077                        48.5923                        0.0000
                      84.1176                         2.7451                       13.1373
                      79.5455                         1.0101                       19.4444
                      51.9205                        48.0795                        0.0000
                      57.2877                         6.5906                       36.1217
                      71.2589                        11.4014                       17.3397
                      56.2624                        43.7376                        0.0000
                      76.4228                         0.0000                       23.5772
                      51.8473                         6.6502                       41.5025
                      74.8555                        25.1445                        0.0000
                      85.8254                        14.1746                        0.0000
                      63.2754                         0.7444                       35.9801
""")

df = (
    pandas.read_csv(data, sep='\s+')
        .stack()
        .to_frame('Safety Margin')
        .reset_index(level=0, drop=True)
        .assign(Distribution=lambda df: df.index.str.rsplit('_', 1).map(lambda x: int(x[-1])))
        .reset_index(drop=True)
        .pipe((seaborn.FacetGrid, 'data'), hue='Distribution', size=5)
        .map(seaborn.distplot, 'Safety Margin', kde=False, bins=range(0, 100, 5))
        .add_legend()
)

Я не говорю, что это лучше, чем циклответы на основе.Но могут быть преимущества при работе с аккуратными данными и отображением в сетке фасетов (например, если вы решите разбить график дальше на строки и столбцы)

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