проблема индексации и сортировки в барплоте - PullRequest
0 голосов
/ 07 октября 2018

Я извлек X и Y из моего кадра данных следующим образом: X это UInt64Index([19, 35, 29, 10, 5, 9, 45, 72, 3, 18], dtype='uint64') и Y это array([14336, 6812, 4265, 3857, 2960, 1986, 1730, 1233, 1128, 841]).

Теперь я хочу использовать sns.barplot длясюжет X против Y.Это означает, что на графике я должен видеть, что, например, X=19 имеет самое высокое значение в Y, которое равно 14336.

Когда я использую

ax=sns.barplot(X, Y)
# add the values of each x index on the bars in the barplot
for p, q in zip(ax.patches, Y):
    ax.text(p.get_x()+p.get_width()/2.,
        p.get_height()*(1.01),
        "{}".format(q),
        ha = 'center'
       )

, я вижу следующий график: enter image description here

К сожалению, я вижу разные значения!Очевидно, sns.barplot сортирует X (от малого к большому значению), однако это не меняет связанное значение в Y.

Кто-нибудь знает, как это решить?

спасибо!

Ответы [ 3 ]

0 голосов
/ 07 октября 2018

Это будет зависеть от того, что вы хотите показать,

все бары упорядочены по размеру

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


X = np.array([19, 35, 29, 10, 5, 9, 45, 72, 3, 18])
Y = np.array([14336,  6812,  4265,  3857,  2960,  1986,  1730,  1233,  1128, 841])

ax = sns.barplot(X,Y, order=X)
for p, q in zip(ax.patches, Y):
    ax.text(p.get_x()+p.get_width()/2.,
        p.get_height()*(1.01),
        "{}".format(q),
        ha = 'center'  )
plt.show()

enter image description here

все барыупорядочено по значению х

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


X = np.array([19, 35, 29, 10, 5, 9, 45, 72, 3, 18])
Y = np.array([14336,  6812,  4265,  3857,  2960,  1986,  1730,  1233,  1128, 841])

ax = sns.barplot(X,Y)
for p, q in zip(ax.patches, Y[np.argsort(X)]):
    ax.text(p.get_x()+p.get_width()/2.,
        p.get_height()*(1.01),
        "{}".format(q),
        ha = 'center'  )
plt.show()

enter image description here

0 голосов
/ 07 октября 2018

ИМХО Я думаю, что вы можете добиться своего результирующего сюжета намного проще.Почему вы рассчитываете отдельные массивы X и Y;Морской рожок создан для работы с пандами.Почему вы рассчитываете свои позиции текста?Они уже там:

Предположим, у вас есть фрейм данных

df = pd.DataFrame([14336, 6812, 4265, 3857, 2960, 1986, 1730, 1233, 1128, 841], index=[19, 35, 29, 10, 5, 9, 45, 72, 3, 18])

Затем вы можете построить его непосредственно с помощью

ax=sns.barplot(x=df.index, y=0, data=df, order=df.index)

И распечатать значения поверхбары, как у вас, просто были бы

for i, y in enumerate(df[0]):
    ax.text(i, 1.01*y, str(y), ha='center')

Однако я бы использовал постоянный разрыв между барами и значениями, а не тот, который масштабируется с высотой бара ...

edit:
Мое мнение о лучшей альтернативе для вычисления отдельных X и Y, как в вопросе:

Вы можете извлечь подсерии из кадра данных.Предположим, ваш исходный фрейм данных называется df:

s = df[df.is_attributed==1].app.value_counts()

И команда plot немного меняется на

ax = sns.barplot(x=s.index, y=s, order=s.index)

... и, конечно, текстовый цикл:

for i, y in enumerate(s):
    ax.text(i, 1.01*y, str(y), ha='center')
0 голосов
/ 07 октября 2018

Я использовал строки вместо целых чисел для X и заказал их вручную.

import seaborn as sns
import matplotlib.pyplot as plt


print "hello"

X = ["19", "35", "29", "10", "5", "9", "45", "72", "3", "18"]

order = ["19", "35", "29", "10", "5", "9", "45", "72", "3", "18"]

Y = [14336,  6812,  4265,  3857,  2960,  1986,  1730,  1233,  1128, 841]

ax=sns.barplot(X,Y, order=order)
# add the values of each x index on the bars in the barplot
for p, q in zip(ax.patches, Y):
    ax.text(p.get_x()+p.get_width()/2.,
        p.get_height()*(1.01),
        "{}".format(q),
        ha = 'center'
       )

plt.show()
...