【问题标题】:Matplotlib stacked bar plot: need to swap x and heightMatplotlib 堆积条形图:需要交换 x 和高度
【发布时间】:2019-06-03 18:28:15
【问题描述】:

我正在查看一些世界生态足迹数据,我想为每种类型的足迹制作一个堆叠条形图,其中堆叠的值相同,但针对不同的国家/地区。所以我开始使用其中的 2 个脚印,只是为了让某些东西发挥作用。

这就是我要做的(有点):

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Create DataFrame from CSV file
df = pd.read_csv('countries.csv')

# Slice Series out of DF
cropFoot = df['Cropland Footprint']
grazeFoot = df['Grazing Footprint']

# Convert Series to list
cropFoot = list(cropFoot)
grazeFoot = list(grazeFoot)

X = range(163)    # the lists have 163 entries

plt.bar(X, height=cropFoot)
plt.bar(X, height=grazeFoot, bottom = cropFoot)
plt.show()

这会产生以下情节:

我想在 x 轴上显示 5 个单独的足迹,以便每个国家/地区的足迹数据堆叠在一起。本质上,现在 x 轴显示了所有 163 个国家/地区,其中 2 个足迹堆叠在一起。我想要相反的。所以我想要 5 个条形图,每个条形图上堆放 163 个国家/地区。

类似这样的东西(但堆叠了 163 件,而不是 7 件):

不出所料,只是交换 X 和高度...不起作用。结果根本没有任何意义:

plt.bar(cropFoot, height=X)
plt.bar(grazeFoot, height=X, bottom = cropFoot)

plt.show()

看起来像这样:

关于如何正确扭转这种情况的任何建议? This is the dataset I'm using,来自 Kaggle。

【问题讨论】:

    标签: python python-3.x matplotlib stacked-chart


    【解决方案1】:

    由于您已经在使用数据框,您可能想尝试使用提供的bar plot 方法,该方法更易于使用。要堆叠,只需设置参数stacked=True。但是,堆叠的是列名,因此您必须先转置您的数据框。它可能看起来像这样:

    footprints = ['Cropland Footprint', 'Grazing Footprint', ...]  # fill with other footprints
    data = df[footprints].T
    data.plot.bar(stacked=True, legend=False)  # you probably don't want a legend with 163 countries
    

    举个例子:

    df = pd.DataFrame(
        np.arange(200).reshape(40, 5),
        index=[f'i{x}' for x in range(40)],
        columns=[f'c{x}' for x in range(5)]
    )
    df.T.plot.bar(stacked=True, legend=False)
    

    【讨论】:

      【解决方案2】:

      我认为@busybear 使用数据框条形图的答案更好,但我认为展示使用matplotlib.pyplot.bar 的解决方案可能是合适的,因为为了完整性,这是问题所在。

      import pandas as pd
      import numpy as np
      import matplotlib.pyplot as plt
      
      # Creates a randomized set of data to use for demonstration
      n = 163
      m = 5
      footprints = np.zeros((m, n))
      for ii in range(n):
          for jj in range(m):
              footprints[jj][ii] = random.random()*10
      
      # This line is unnecessary for the example, it is purely for plot aesthetic
      fig = plt.figure(figsize=(5, 5), dpi=200)
      
      # colors can be replaced with any list of colors of any length >= 1
      colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
      bottom = np.zeros(5)
      for ii in range(1, n):
          for jj in range(m):
              plt.bar(jj, height=footprints[jj][ii], bottom=bottom[jj], 
                      color=colors[ii % len(colors)])
              bottom[jj] = bottom[jj] + footprints[jj][ii]
      
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 2018-01-17
        • 2019-11-28
        • 1970-01-01
        • 2017-11-02
        • 2021-02-27
        • 1970-01-01
        • 2013-03-31
        相关资源
        最近更新 更多