【问题标题】:problem of indexing and sorting in barplotbarplot中的索引和排序问题
【发布时间】:2019-03-12 06:41:21
【问题描述】:

我从我的数据框中提取了XY,如下所示: XUInt64Index([19, 35, 29, 10, 5, 9, 45, 72, 3, 18], dtype='uint64')Yarray([14336, 6812, 4265, 3857, 2960, 1986, 1730, 1233, 1128, 841])

现在我想使用sns.barplot 来绘制XY 的对比。这意味着在情节中我必须看到,例如X=19Y 中具有最高的相关值,即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'
       )

我看到以下情节:

不幸的是,我看到了不同的价值观!显然sns.barplotX 进行排序(从小到大的值),但是它不会改变Y 中的相关值。

有没有人有办法解决这个问题?

谢谢!

【问题讨论】:

  • 您能否在您的问题中提供所需的行为、特定问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example。”
  • 您好,Artem。我已经添加了完整的代码。从图中可以看出,19(在 x 轴上)具有最高值(条形最大),但是,条形上方的值是 1986(而不是 14336)。另一个例子是 X=18(这是 X 的最后一个数字)对应的值是 841(在 Y 数组中),但是,在图中是 2960。(实际上,841 现在考虑 X 轴上 72 的对应值.)
  • 谢谢,点赞。

标签: python matplotlib bar-chart seaborn


【解决方案1】:

这取决于你想展示什么,

所有条形按大小排序

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()

所有条形按 x 值排序

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()

【讨论】:

  • 太棒了!谢谢!
【解决方案2】:

我对 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()

【讨论】:

  • 感谢您的回答!我想即使是字符串也是按 sns.barplot 排序的。因为在 x 轴上我看到 (10, 18, 19, 29, 3, 35, 45, 5, 72, 9)。出于这个原因,我仍然得到不完全正确的情节。我的意思是在每一个栏上,写的数字都不正确。
  • 我认为编辑解决了它,甚至可能没有将 X 更改为字符串,但只是使用 order 参数。
  • 太棒了!谢谢! :)
【解决方案3】:

恕我直言,我认为您可以更简单地实现您的结果图。为什么要计算单独的 X 和 Y 数组; seaborn 可以与 pandas 一起工作。你为什么要计算你的文本位置?他们已经在那里了:

假设你有一个数据框

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')

但是,我会使用条形图和值之间的恒定间隙,而不是随条形图高度缩放的...

编辑:
我认为可以更好地替代像问题中那样计算单独的 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')

【讨论】:

  • 嗨。感谢您的回复。基本上我在这里带来了我的问题的简化版本。在某些条件下,X 和 Y 都是从数据帧中提取的。考虑一个 Dataframe df,它有两个特性(1.app,2.is_attributed)。然后我按如下方式构造了 X 和 Y:X= df[df.is_attributed==1]['app'].value_counts()[:10].indexY=df[df.is_attributed==1]['app'].value_counts()[:10].values。这就是我没有使用 DataFrame 来绘制它的原因。但是,我喜欢您提供解决方案的方式,尤其是在条形顶部打印值的最后一部分:)
  • 好的,明白了。但是,请让我再提供两个提示: 1. 索引是保留在 subdstaframe 或子系列中的某物 - 您不必手动保存它 2. “从不进行括号链接”是 pandas 最著名的规则之一。如果需要,请改用df.loc
猜你喜欢
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多