Как построить фасетную гистограмму с настраиваемыми ячейками с переполнением / переполнением в Python3? - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть pandas фрейм данных с несколькими столбцами (регион, дата, прибыль). Я хотел бы получить гистограмму прибыли с учетом региона и даты. Но данные столбца прибыли имеют длинный хвост на каждой стороне, означая, что есть 5 показателей прибыли менее 10 долларов, и 280483 счета прибыли между 400-450 долларов, а затем 6 показателей прибыли, превышающих 100000 долларов.

Я хотел бы создать гистограмму с настраиваемыми ячейками так, чтобы она отображала несколько корзин для 400-450 долларов США и всего 1 ячейку для менее 400 долларов США и 1 ячейку для 450 долларов США, и, надеюсь, столбцы в гистограмме будут выше той же. ширина.

То, что у меня сейчас есть:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
fixed_bin = list(np.arange(400,450,5))
fixed_bin.insert(0,0)
fixed_bin.append(150000)
fig = sns.FacetGrid(df, col = 'region', row = 'date',
                    margin_titles = True, aspect = 1.4)
fig.map(sns.distplot, 'profit', kde = False, bins = fixed_bin, color = 'r')

Однако, это дает мне равномерно распределенную ось X, которая идет от 0 до 150000. Все мои данные (между 400-450) все еще сжимается в середине и трудно увидеть настоящую гистограмму для этой средней части. Как я могу сделать хвосты на обоих концах (контейнеры с переполнением и переполнением) в две небольшие корзины, которые имеют такую ​​же ширину, что и корзины в середине?

Большое спасибо за вашу помощь !!

1 Ответ

1 голос
/ 16 апреля 2020

Моей первой мыслью было сделать биннинг и черчение отдельно. Но я не смог найти, чтобы matplotlib.pyplot.bar или seaborn.barplot предлагали нестандартные размеры бинов.

Так что нам нужно обмануть seaborn.distplot или matplotlib.pyplot.hist (функция, стоящая за ним).

import numpy as np

import seaborn as sns
import matplotlib.pyplot as plt

# add another bin to dump all overflow values
# same size as the others
fixed_bin = list(np.arange(400, 455, 5))

# add another bin to dump all underflow values
# same size as the others
fixed_bin.insert(0, 395)

print(fixed_bin)

some_upper_boundary = 500

data = np.random.randint(300, high=some_upper_boundary, size=1000)

# use boolean indexing do move the data from 450 to 150000 into the
# last bin

in_first_bin = np.logical_and(data >= 0, data < 400)
in_last_bin = np.logical_and(data > 450, data <= some_upper_boundary)

data[in_first_bin] = 397
data[in_last_bin] = 447

#print(data)
ax = sns.distplot(data, bins=fixed_bin)


# Set the tick positions
ax.set_xticks(fixed_bin)

my_custom_ticklabels = list(map(str, fixed_bin))
print(my_custom_ticklabels)

my_custom_ticklabels[0] = 'under\nflow'
my_custom_ticklabels[-1] = 'over\nflow'

# Set the tick labels
ax.set_xticklabels(my_custom_ticklabels)

plt.show()

Я добавлю немного форматирования позже:

  • добавим метку галочки на график. Последний лоток может быть «после».
  • проделайте тот же трюк для первого лотка и установите метку «до».

enter image description here

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