【问题标题】:Stacking 3 bars on top of each other via Python's Matplotlib通过 Python 的 Matplotlib 堆叠 3 个条形图
【发布时间】:2014-08-01 19:32:19
【问题描述】:

我想创建一个堆叠的条形图,其中 3 个条相互重叠。我设法为 2 条堆叠做到了这一点,但我无法添加第 3 条,有什么想法吗?

我将添加一些简单的示例代码来说明我的意思:

from matplotlib import pyplot as plt

data1 = [100,120,140]
data2 = [150,120,190]

f, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,5))

## Absolute count

ax1.bar(range(len(data1)), data1, label='data 1', alpha=0.5, color='b')
ax1.bar(range(len(data2)), data2, bottom=data1, label='data 2', alpha=0.5, color='r')
plt.sca(ax1)
plt.xticks([0.4, 1.4, 2.4],  ['category 1', 'category 2', 'category 3'])
ax1.set_ylabel("Count")
ax1.set_xlabel("")
plt.legend(loc='upper left')

## Percent

totals = [i + j for i,j in zip(data1, data2)]
data1_rel = [i / j * 100 for  i,j in zip(data1, totals)]
data2_rel = [i / j * 100 for  i,j in zip(data2, totals)]

ax2.bar(range(len(data1_rel)), data1_rel, alpha=0.5, color='b')
ax2.bar(range(len(data2_rel)), data2_rel, bottom=data1_rel, alpha=0.5, color='r')
plt.sca(ax2)
plt.xticks([0.4, 1.4, 2.4],  ['category 1', 'category 2', 'category 3'])
ax2.set_ylabel("Percentage")
ax2.set_xlabel("")

plt.show()

现在,假设我要添加,例如,data3 = [100,150,130] 直觉上,我会这样做

ax1.bar(range(len(data3)), data3, bottom=data1+data2, label='data 3', alpha=0.5, color='g')

但是,不幸的是,这并没有添加第三条。

【问题讨论】:

    标签: python matplotlib bar-chart


    【解决方案1】:

    应该这样做:ax1.bar(range(len(data3)), data3, bottom=np.array(data1)+np.array(data2), label='data 3', alpha=0.5, color='g'):

    而且,可能是首选方式。 pandas 只需几行就可以非常优雅地处理它:

    In [17]:
    
    import pandas as pd
    df=pd.DataFrame({'data1':data1, 'data2':data2, 'data3':data3})
    df.plot(kind='bar', stacked=True)
    Out[17]:
    <matplotlib.axes.AxesSubplot at 0x108f2b050> 
    

    【讨论】:

      【解决方案2】:

      如果您想使用 pandas 绘图库而不是 matplotlib 的选项:

      import pandas
      
      column_names = ['cat1', 'cat2', 'cat3']
      data1 = [100,120,140]
      data2 = [150,120,190]
      data3 = [100,150,130]
      
      df = pandas.DataFrame([data1, data2, data3], columns = column_names)
      df.plot.bar(stacked=True)
      

      【讨论】:

        【解决方案3】:

        我假设您在尝试绘图时遇到错误?

        目前,您正在使用列表等:

        >>> data1 = [1, 2, 3]
        >>> data2 = [4, 5, 6]
        
        >>> data+data2
        >>> [1, 2, 3, 4, 5, 6]
        

        您可以使用例如 numpy 数组,这应该可以解决您的问题。

        >>> data1 = numpy.array([1, 2, 3])
        >>> data2 = numpy.array([4, 5, 6])
        
        >>> data1+data2
        >>> [5, 7, 9]
        

        【讨论】:

          【解决方案4】:

          这个怎么样?它似乎对我有用。

          from __future__ import division
          from matplotlib import pyplot as plt
          
          data1 = [100,120,140]
          data2 = [150,120,190]
          data3 = [130,110,120]
          
          f, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,5))
          
          ## Absolute count
          
          b = list(r_[data1] +r_[ data2])
          
          ax1.bar(range(len(data1)), data1, label='data 1', alpha=0.5, color='b')
          ax1.bar(range(len(data2)), data2, bottom=data1, label='data 2', alpha=0.5, color='r')
          ax1.bar(range(len(data3)), data3, bottom=b, label='data 3', alpha=0.5, color='g')
          plt.sca(ax1)
          plt.xticks([0.4, 1.4, 2.4],  ['category 1', 'category 2', 'category 3'])
          ax1.set_ylabel("Count")
          ax1.set_xlabel("")
          plt.legend(loc='upper left')
          
          ## Percent
          
          totals = [i + j + k for i,j,k in zip(data1, data2, data3)]
          data1_rel = [i / j * 100 for  i,j in zip(data1, totals)]
          data2_rel = [i / j * 100 for  i,j in zip(data2, totals)]
          data3_rel = [i / j * 100 for  i,j in zip(data3, totals)]
          
          b_rel = list(r_[data1_rel] +r_[ data2_rel] )
          
          
          ax2.bar(range(len(data1_rel)), data1_rel, alpha=0.5, color='b')
          ax2.bar(range(len(data2_rel)), data2_rel, bottom=data1_rel, alpha=0.5, color='r')
          ax2.bar(range(len(data3_rel)), data3_rel, bottom=b_rel, alpha=0.5, color='g')
          plt.sca(ax2)
          plt.xticks([0.4, 1.4, 2.4],  ['category 1', 'category 2', 'category 3'])
          ax2.set_ylabel("Percentage") 
          ax2.set_xlabel("")
          
          plt.show()
          

          【讨论】:

            猜你喜欢
            • 2020-09-26
            • 2019-05-30
            • 2017-03-28
            • 2021-10-22
            • 1970-01-01
            • 2023-01-21
            • 2018-10-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多