Seaborn Barplot - отображение значений

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

1) Я хочу отобразить значения одного поля в кадре данных при построении графика другого. Например, ниже я отображаю график "tip", но я бы хотел разместить значение "total_bill" с центром над каждым из баров (т.е. 325,88 выше пятницы, 1778,40 выше субботы и т.д.)

2) Есть ли способ масштабировать цвета баров, при этом самое низкое значение "total_bill" имеет самый светлый цвет (в данном случае пятница), а самое высокое значение "total_bill" - самое темное. Очевидно, что я буду придерживаться одного цвета (то есть синего), когда я делаю масштабирование.

Спасибо! Я уверен, что это легко, но мне не хватает этого..

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

Начиная со следующего кода,

import pandas as pd
import seaborn as sns
%matplotlib inline
df=pd.read_csv("https://raw.githubusercontent.com/wesm/pydata-    book/master/ch08/tips.csv", sep=',')
groupedvalues=df.groupby('day').sum().reset_index()
g=sns.barplot(x='day',y='tip',data=groupedvalues)

Я получаю следующий результат:

enter image description here

Временное решение:

for index, row in groupedvalues.iterrows():
    g.text(row.name,row.tip, round(row.total_bill,2), color='black', ha="center")

enter image description here

На затенении, используя приведенный ниже пример, я попробовал следующее:

import pandas as pd
import seaborn as sns
%matplotlib inline
df=pd.read_csv("https://raw.githubusercontent.com/wesm/pydata-book/master/ch08/tips.csv", sep=',')
groupedvalues=df.groupby('day').sum().reset_index()

pal = sns.color_palette("Greens_d", len(data))
rank = groupedvalues.argsort().argsort() 
g=sns.barplot(x='day',y='tip',data=groupedvalues)

for index, row in groupedvalues.iterrows():
    g.text(row.name,row.tip, round(row.total_bill,2), color='black', ha="center")

Но это дало мне следующую ошибку:

AttributeError: у объекта DataFrame нет атрибута argsort

Итак, я попробовал модификацию:

import pandas as pd
import seaborn as sns
%matplotlib inline
df=pd.read_csv("https://raw.githubusercontent.com/wesm/pydata-book/master/ch08/tips.csv", sep=',')
groupedvalues=df.groupby('day').sum().reset_index()

pal = sns.color_palette("Greens_d", len(data))
rank=groupedvalues['total_bill'].rank(ascending=True)
g=sns.barplot(x='day',y='tip',data=groupedvalues,palette=np.array(pal[::-1])[rank])

и это оставляет меня с

IndexError: индекс 4 выходит за пределы оси 0 с размером 4

Ответ 1

Давайте придерживаться решения из связанного вопроса (Изменение цветовой шкалы на графике морского бора). Вы хотите использовать argsort, чтобы определить порядок цветов, используемых для окрашивания полос. В связанном вопросе argsort применяется к объекту Series, который работает нормально, в то время как здесь у вас есть DataFrame. Поэтому вам нужно выбрать один столбец этого DataFrame, чтобы применить argsort.

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

df = sns.load_dataset("tips")
groupedvalues=df.groupby('day').sum().reset_index()

pal = sns.color_palette("Greens_d", len(groupedvalues))
rank = groupedvalues["total_bill"].argsort().argsort() 
g=sns.barplot(x='day',y='tip',data=groupedvalues, palette=np.array(pal[::-1])[rank])

for index, row in groupedvalues.iterrows():
    g.text(row.name,row.tip, round(row.total_bill,2), color='black', ha="center")

plt.show()

enter image description here


Вторая попытка также работает нормально, единственная проблема заключается в том, что ранг, возвращаемый rank() начинается с 1 а не с нуля. Таким образом, нужно вычесть 1 из массива. Также для индексации нам нужны целочисленные значения, поэтому нам нужно привести его к int.
rank = groupedvalues['total_bill'].rank(ascending=True).values
rank = (rank-1).astype(np.int)

Ответ 2

Работает с одним топором или с матрицей топора (подзаговоры)

from matplotlib import pyplot as plt
import numpy as np

def show_values_on_bars(axs):
    def _show_on_single_plot(ax):        
        for p in ax.patches:
            _x = p.get_x() + p.get_width() / 2
            _y = p.get_y() + p.get_height()
            value = '{:.2f}'.format(p.get_height())
            ax.text(_x, _y, value, ha="center") 

    if isinstance(axs, np.ndarray):
        for idx, ax in np.ndenumerate(axs):
            _show_on_single_plot(ax)
    else:
        _show_on_single_plot(axs)

fig, ax = plt.subplots(1, 2)
show_values_on_bars(ax)

Ответ 3

На всякий случай, если кто-то заинтересован в маркировке горизонтального графика, я изменил ответ Шарона, как показано ниже:

def show_values_on_bars(axs, h_v="v", space=0.4):
    def _show_on_single_plot(ax):
        if h_v == "v":
            for p in ax.patches:
                _x = p.get_x() + p.get_width() / 2
                _y = p.get_y() + p.get_height()
                value = int(p.get_height())
                ax.text(_x, _y, value, ha="center") 
        elif h_v == "h":
            for p in ax.patches:
                _x = p.get_x() + p.get_width() + float(space)
                _y = p.get_y() + p.get_height()
                value = int(p.get_width())
                ax.text(_x, _y, value, ha="left")

    if isinstance(axs, np.ndarray):
        for idx, ax in np.ndenumerate(axs):
            _show_on_single_plot(ax)
    else:
        _show_on_single_plot(axs)

Два параметра объяснили:

h_v - горизонтальный или вертикальный барплот "h" представляет горизонтальный график, "v" представляет вертикальный график.

space - пространство между текстом значения и верхним краем панели. Работает только в горизонтальном режиме.

Пример:

show_values_on_bars(sns_t, "h", 0.3)

enter image description here

Ответ 4

Надеюсь, что это поможет для пункта № 2: a) Вы можете сортировать по общей сумме, затем reset индекс в этот столбец б) Используйте палитру = "Синий", чтобы использовать этот цвет, чтобы масштабировать диаграмму от светло-голубого до синего (если синий или синий, а затем используйте палитру = "Blues_d" )

import pandas as pd
import seaborn as sns
%matplotlib inline

df=pd.read_csv("https://raw.githubusercontent.com/wesm/pydata-book/master/ch08/tips.csv", sep=',')
groupedvalues=df.groupby('day').sum().reset_index()
groupedvalues=groupedvalues.sort_values('total_bill').reset_index()
g=sns.barplot(x='day',y='tip',data=groupedvalues, palette="Blues")