Бокплоты с перекрывающимся распределением / гистограммой - PullRequest
0 голосов
/ 08 октября 2019

Короче говоря: я в основном пытаюсь нарисовать блокпост, основанный на непрерывной переменной, где каждый блок представляет записи в определенном диапазоне этой переменной. И вдобавок ко всему, я хочу наложить гистограмму, чтобы показать распределение (сколько счетчиков в каждом интервале).

Немного более объяснено: у меня есть фрейм данных с различными столбцами. Мне интересно сгруппировать их по интервалам в определенном непрерывном столбце X и нарисовать блок-график того, как столбец Y выглядит для каждого интервала столбца X. Кроме того, я хотел бы наложить распределение или гисторгам, чтобы показать, сколько элементов на каждомboxplot, более или менее.

Я попытался (и не смог) построить гистограмму с помощью дополнительных контейнеров. Затем классифицируем данные в соответствии со средним значением каждого бина, чтобы я мог построить оба (гистограмма и блок-график) на одной и той же оси или использовать одну и ту же ось X (axes.twinx()), но затем гистограмма деформируется. Это похоже на то, что он не распознает значения для оси X как одинаковые.

Исходная гистограмма: https://imgur.com/8iNnR2u

После попытки добавить графы: https://imgur.com/0LRGTTp

Вот иллюстративный пример того, что я пытался сделать:

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


# Generate random data
prices = np.random.uniform(low=-85.0,high=85.0, size=(50,))
value_x = np.random.uniform(low=0,high=3000.0, size=(50,))
df = pd.DataFrame({'price':prices,'value_x':value_x })
# Classify each entry according to the bin they belong to
df['interval_index'] = np.digitize(df['price'], np.arange(-85,85,5))
# Get middle value for each bin, for example, if bin is (40-45), middle value would be 42.5
df['interval_middle_value'] = df['interval_index']*5-87.5

# Failed attempt to generate the desired plot
fig, ax = plt.subplots()
sns.distplot(df['price'],bins=np.arange(-85,85,5), ax=ax, kde=False, norm_hist=False)
ax2=ax.twinx()
sns.boxplot(x='interval_middle_value',y='value_x',data=df, ax=ax2)

Я ожидал бы результат, подобный следующему графику: https://imgur.com/svEOlNQ

1 Ответ

1 голос
/ 08 октября 2019

Поскольку блок-схема является категориальной, вам необходимо установить позиции блоков в середине интервалов корзины. Следовательно, вероятно, вы ищете что-то вроде этого:

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

# Generate random data
prices = np.random.uniform(low=-85.0,high=85.0, size=(500,))
value_x = np.random.uniform(low=0,high=3000.0, size=(500,))
df = pd.DataFrame({'price':prices,'value_x':value_x })
# Classify each entry according to the bin they belong to
bins = np.arange(-85,90,5)

width = np.diff(bins)[0]
df['interval_index'] = np.digitize(df['price'], bins)
# Get middle value for each bin, for example, if bin is (40-45), middle value would be 42.5
middle_value = bins[:-1] + width/2

# Failed attempt to generate the desired plot
fig, ax = plt.subplots()
ax.hist(df['price'].values, bins=bins)
ax2=ax.twinx()

stats = [df['value_x'][df['interval_index'] == i].values for i in range(1, len(bins))]
ax2.boxplot(stats, positions=middle_value, widths=width*0.6, manage_ticks=False)


plt.show()

enter image description here

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