Как создать две отдельные оси Y для гистограммы на одном рисунке в Seaborn

Я хотел бы создать одну фигуру с двумя осями Y: Count (из гистограммы) и Density (из KDE).

Я хочу использовать sns.displot в Seaborn >= v 0.11.

import seaborn as sns

df = sns.load_dataset('tips')

# graph 1: This should be the Y-Axis on the left side of the figure
sns.displot(df['total_bill'], kind='hist', bins=10)

# graph 2: This should be the Y-axis on the right side of the figure
sns.displot(df['total_bill'], kind='kde')

Написанный мной код генерирует два отдельных графика; Я мог бы просто использовать сетку фасетов для двух отдельных графиков, но я хочу быть более кратким и поместить две оси Y на двух отдельных сетках в одну фигуру, разделяющую одну и ту же ось X.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
5 997
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

displot() — это функция уровня фигуры, которая может создавать несколько подзаголовков внутри фигуры. Таким образом, у вас нет контроля над отдельными осями.

Для создания комбинированных графиков можно использовать базовые функции уровня осей: histplot() и kdeplot() для Seaborn v.0.11. Эти функции принимают параметр ax=. twinx() создает вторую ось Y.

import matplotlib.pyplot as plt
import seaborn as sns

df = sns.load_dataset('tips')

fig, ax = plt.subplots()

sns.histplot(df['total_bill'], bins=10, ax=ax)

ax2 = ax.twinx()
sns.kdeplot(df['total_bill'], ax=ax2)

plt.tight_layout()
plt.show()

Редактировать:

Как упоминалось в комментариях, оси Y не выровнены. Левая ось только что-то говорит о гистограмме. Например. самая высокая корзина с высотой 68 означает, что между 12.618 и 17.392 всего ровно 68 купюр. Правая ось говорит только что-то о kde. Например. значение y 0.043 для x=20 будет означать, что вероятность того, что общий счет будет между 19.5 и 20.5, составляет около 4,3%.

Чтобы выровнять оба, подобные sns.histplot(..., kde=True), можно рассчитать площадь гистограммы (ширина интервала, умноженная на количество значений данных) и использовать в качестве коэффициента масштабирования. Такое масштабирование сделало бы площадь гистограммы и площадь под кривой kde равными при измерении в пикселях:

num_bins = 10
bin_width = (df['total_bill'].max() - df['total_bill'].min()) / num_bins
hist_area = len(df) * bin_width
ax2.set_ylim(ymax=ax.get_ylim()[1] / hist_area)

Обратите внимание, что правая ось была бы больше похожа на процент, если бы гистограмма использовала ширину бина со степенью десяти (например, sns.histplot(..., bins=np.arange(0, df['total_bill'].max()+10, 10)). Какие бины будут наиболее подходящими, сильно зависит от того, как вы хотите интерпретировать свои данные.

Хорошее объяснение различий между уровнями фигуры и уровня осей, но если вам буквально нужна кривая KDE поверх гистограммы, вы должны добавить kde=True к вызову histplot (или displot). Правда, это не даст вам обе оси Y, но на самом деле они здесь не эквивалентны, как предполагает сюжет (ограничения устанавливаются автоматическим масштабированием matplotlib для художников, а не математическим соотношением между количеством / плотностью) и осью плотности все равно толком не интерпретируется.

mwaskom 22.12.2020 01:58

Хорошая проработка; вы точно правильно интерпретируете значение плотности в своем редактировании. Просто отметим для других, что «плотность» как значение оси Y имеет очень высокую вероятность неправильного толкования, поэтому будьте осторожны при отображении такого графика.

mwaskom 22.12.2020 14:48

Другие вопросы по теме