Построение центральных тенденций (среднее, медиана, мода) в подграфиках Seaborn

Вопрос или проблема

У меня ошибка, когда я пытаюсь запустить этот код

import pandas as pd
import numpy as np
import seaborn as sns
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable

import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
sns.set_theme()
sns.set_style('white')

df_train = pd.read_csv('https://github.com/lokalhangatt/stackoverlow/raw/refs/heads/main/train.csv')

df_train = df_train.dropna(axis=1)

null_info = df_train.isnull().sum().sort_values(ascending=False).reset_index().head(20)
null_info.columns = ["Переменная", "Пропущенное значение"]

list_soal = ['SalePrice', 'GrLivArea', 'GarageArea']

# fig,ax = plt.subplots(1, 3, sharey=True, figsize=(14,4))
def function1(ax):
    ax[1].set_title('Гистограмма для не трансформированных данных', fontsize=16)
    for i in range(len(list_soal)):
        sns.histplot(df_train[list_soal[i]], kde=False, stat="density", bins = 30, ax=ax[i])
        sns.kdeplot(df_train[list_soal[i]], ax=ax[i])
    for j in range(len(list_soal)):
        line1 = plt.axvline(df_train[list_soal].mean(), color="k", linestyle="--", label = "среднее")
        line2 = plt.axvline(np.median(df_train[list_soal]), color="r", linestyle="--", label = "медиана")
        first_legend = plt.legend(handles=[line1,line2], loc=1)

# fig,ax = plt.subplots(1, 3, sharey=True, figsize=(14,4))
def function2(ax):
    ax[1].set_title('Гистограмма для трансформированных данных', fontsize=16)
    for i in range(len(list_soal)):
        sns.histplot(np.log10(df_train[list_soal[i]]), kde=False, stat="density", bins = 30, ax=ax[i])
        sns.kdeplot(np.log10(df_train[list_soal[i]]), ax=ax[i])

fig,ax = plt.subplots(2, 3, figsize=(14,9), sharey='row')
fig.subplots_adjust(hspace=0.4)


function1(ax[0])
function2(ax[1])

plt.show()

Я хочу отобразить центральные тенденции на каждом субплоте, который я запускаю. Вот мои субплоты:
вставьте описание изображения сюда

Это должно показать центральную тенденцию каждого бокса на субплотах. Но когда я пытаюсь запустить код выше, я получаю ошибку, которая говорит:

ValueError: Истинное значение серии неоднозначно. Используйте a.empty, a.bool(), a.item(), a.any() или a.all().

Как я могу показать эти центральные тенденции на каждом субплоте?

Ответ или решение

Для успешного построения субплотов с центральными тенденциями (среднее, медиана, мода) в библиотеке Seaborn и устранения ошибки, с которой вы столкнулись, необходимо внести некоторые изменения в ваш исходный код. Ошибка ValueError: The truth value of a Series is ambiguous возникает, когда вы пытаетесь передать целую серию данных в функцию, которая ожидает одиночное значение.

Расмотрим обновленный код, в который включены необходимые исправления для правильного отображения центральных тенденций для каждого графика в субплотах.

Исправленный код для построения субплотов с центральными тенденциями

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

# Настройка стиля и темы
sns.set_theme()
sns.set_style('white')

# Загрузка данных
df_train = pd.read_csv('https://github.com/lokalhangatt/stackoverlow/raw/refs/heads/main/train.csv')
df_train = df_train.dropna(axis=1)

# Определение переменных для анализа
list_soal = ['SalePrice', 'GrLivArea', 'GarageArea']

# Функция для построения гистограмм для не трансформированных данных
def function1(ax):
    ax[1].set_title('Histogram for Non-Transformed Data', fontsize=16)
    for i in range(len(list_soal)):
        sns.histplot(df_train[list_soal[i]], kde=False, stat="density", bins=30, ax=ax[i])
        sns.kdeplot(df_train[list_soal[i]], ax=ax[i])

        # Добавление линий для среднего и медианы
        ax[i].axvline(df_train[list_soal[i]].mean(), color="k", linestyle="--", label="mean")
        ax[i].axvline(df_train[list_soal[i]].median(), color="r", linestyle="--", label="median")
        ax[i].legend()

# Функция для построения гистограмм для трансформированных данных
def function2(ax):
    ax[1].set_title('Histogram for Transformed Data', fontsize=16)
    for i in range(len(list_soal)):
        transformed_data = np.log10(df_train[list_soal[i]])
        sns.histplot(transformed_data, kde=False, stat="density", bins=30, ax=ax[i])
        sns.kdeplot(transformed_data, ax=ax[i])

        # Добавление линий для среднего и медианы
        ax[i].axvline(transformed_data.mean(), color="k", linestyle="--", label="mean")
        ax[i].axvline(transformed_data.median(), color="r", linestyle="--", label="median")
        ax[i].legend()

# Настройка субплотов
fig, ax = plt.subplots(2, 3, figsize=(14, 9), sharey='row')
fig.subplots_adjust(hspace=0.4)

# Построение графиков
function1(ax[0])
function2(ax[1])

# Отображение графиков
plt.show()

Пояснения к изменениям

  1. Ошибка передавалась в функции: В оригинальном коде вы использовали df_train[list_soal].mean() и df_train[list_soal].median(), что возвращало Series, а не отдельное значение. Вместо этого мы изменили код, чтобы получать среднее и медиану для каждого элемента в list_soal отдельно.

  2. Легенда на каждом субплоте: Легенды теперь добавляются в цикле для каждого субплота, что улучшает читаемость графиков и позволяет легко различить, какая линия представляет среднее, а какая медиану.

  3. Структурировка кода: Удалены ненужные переменные и неиспользуемые импорты, что делает код более чистым и понятным.

Заключение

Теперь ваш код корректно отображает центральные тенденции для каждого субплота как для не трансформированных, так и для трансформированных данных, и дополнительные изменения упрощают понимание и читабельность графиков. Вы можете адаптировать данный код к своей задаче для изучения различных переменных с помощью Seaborn.

Оцените материал
Добавить комментарий

Капча загружается...