【问题标题】:pyplot bar chart with categories带有类别的 pyplot 条形图
【发布时间】:2017-07-14 13:07:25
【问题描述】:

我有以下熊猫数据框:

    x   y   cat
0   1   2   1
1   2   3   1
2   3   4   1
3   1   2   2
4   2   3   2
5   3   8   2

所以我有一些 x-y 值和一个类别。

现在我想制作一个带有每个 x 值(1,2 和 3)的条形图,两个条形显示两个类别的 y 值。这不应该那么复杂,但由于某种原因,这仍然有效:

ax = plt.subplot(111)
ax.bar(df[df["cat"] == 1]["x"]-0.2, df[df["cat"] == 1]["y"],width=0.2,color='b',align='center')
plt.show()

但是当我添加第二类时:

ax = plt.subplot(111)
ax.bar(df[df["cat"] == 1]["x"]-0.2, df[df["cat"] == 1]["y"],width=0.2,color='b',align='center')
ax.bar(df[df["cat"] == 2]["x"]+0.2, df[df["cat"] == 2]["y"],width=0.2,color='g',align='center')
plt.show()

python 开始抱怨一个关键错误:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-63-2188371c6b12> in <module>()
      1 ax = plt.subplot(111)
      2 ax.bar(df[df["cat"] == 1]["x"]-0.2, df[df["cat"] == 1]["y"],width=0.2,color='b',align='center')
----> 3 ax.bar(df[df["cat"] == 2]["x"]+0.2, df[df["cat"] == 1]["y"],width=0.2,color='b',align='center')
      4 plt.show()

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/__init__.py in inner(ax, *args, **kwargs)
   1890                     warnings.warn(msg % (label_namer, func.__name__),
   1891                                   RuntimeWarning, stacklevel=2)
-> 1892             return func(ax, *args, **kwargs)
   1893         pre_doc = inner.__doc__
   1894         if pre_doc is None:

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/axes/_axes.py in bar(self, left, height, width, bottom, **kwargs)
   2103         if align == 'center':
   2104             if orientation == 'vertical':
-> 2105                 left = [left[i] - width[i] / 2. for i in xrange(len(left))]
   2106             elif orientation == 'horizontal':
   2107                 bottom = [bottom[i] - height[i] / 2.

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/axes/_axes.py in <listcomp>(.0)
   2103         if align == 'center':
   2104             if orientation == 'vertical':
-> 2105                 left = [left[i] - width[i] / 2. for i in xrange(len(left))]
   2106             elif orientation == 'horizontal':
   2107                 bottom = [bottom[i] - height[i] / 2.

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/series.py in __getitem__(self, key)
    601         key = com._apply_if_callable(key, self)
    602         try:
--> 603             result = self.index.get_value(self, key)
    604 
    605             if not is_scalar(result):

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/indexes/base.py in get_value(self, series, key)
   2167         try:
   2168             return self._engine.get_value(s, k,
-> 2169                                           tz=getattr(series.dtype, 'tz', None))
   2170         except KeyError as e1:
   2171             if len(self) > 0 and self.inferred_type in ['integer', 'boolean']:

pandas/index.pyx in pandas.index.IndexEngine.get_value (pandas/index.c:3557)()

pandas/index.pyx in pandas.index.IndexEngine.get_value (pandas/index.c:3240)()

pandas/index.pyx in pandas.index.IndexEngine.get_loc (pandas/index.c:4279)()

pandas/src/hashtable_class_helper.pxi in pandas.hashtable.Int64HashTable.get_item (pandas/hashtable.c:8564)()

pandas/src/hashtable_class_helper.pxi in pandas.hashtable.Int64HashTable.get_item (pandas/hashtable.c:8508)()

KeyError: 0

【问题讨论】:

    标签: python pandas matplotlib bar-chart


    【解决方案1】:

    好的,知道了。

    ax = plt.subplot(111)
    ax.bar( (df[df["cat"] == 1]["x"]-0.2).tolist(), df[df["cat"] == 1]["y"].tolist(),width=0.2,color='b',align='center')
    ax.bar( (df[df["cat"] == 2]["x"]+0.2).tolist(), df[df["cat"] == 2]["y"].tolist(),width=0.2,color='g',align='center')
    plt.show()
    

    问题是df[df["cat"] == 1]["x"] 不返回一个列表而是一个系列,所以包括索引。显然,这个索引实际上被 pyplot 使用,但它实际上不应该在某种程度上使用它。因为如果我们明确地列出它,它就可以工作:

    【讨论】:

      【解决方案2】:

      这也可以作为 pandas 中的单行解决方案:

      df.pivot_table(values='y', index='x', columns='cat').plot.bar()
      

      pivot_table 调用将创建一个如下所示的表:

      cat  1  2
      x        
      1    2  2
      2    3  3
      3    4  8
      

      【讨论】:

        猜你喜欢
        • 2022-01-20
        • 2013-05-18
        • 1970-01-01
        • 1970-01-01
        • 2016-04-20
        • 2013-08-04
        • 2019-02-02
        • 2014-10-22
        • 2012-05-08
        相关资源
        最近更新 更多