【问题标题】:Stacked bar chart from Pandas Dataframe来自 Pandas Dataframe 的堆积条形图
【发布时间】:2018-11-09 15:59:14
【问题描述】:

我有一个数据框“dft”,其中包含两列“月”(可以是 1 月到 12 月)和该月的“支出”。

我正在尝试为这些数据创建一个堆积条形图,堆栈代表 0 到 100 之间的支出; 100 - 500 和 500+;

为了对这些值的数据框进行排序,我编写了以下代码。

small = dft[(dft['Expenditure'] < 100) & (dft['Expenditure'] > 0)]
medium = dft[(dft['Expenditure'] <= 500) & (dft['Expenditure'] >= 100)]
large = dft[(dft['Expenditure'] > 500)] 

有没有一种方法可以直接从 Pandas 将这些数据框绘制在堆积条形图中?该图表的 x 轴表示月份,y 轴表示支出。

【问题讨论】:

  • 不是拆分数据框,而是添加一个带有限定符的新列以堆叠(小、中、大)。然后以该新列为轴旋转框架并使用stacked=True option 进行绘图。

标签: python pandas matplotlib


【解决方案1】:

我尝试创建一个简单的示例(使用原始给定数据)来解决您的问题。您还应该查看文档中的stacked_bar_chart。要转换月份并“填充”数据,您可以使用以下方法:

import numpy as np
import matplotlib.pyplot as plt

# given x data
x1 = ['January', 'October', 'November', 'December']
x2 = ['January', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
x3 = ['January', 'November', 'December']

# given y data
y1 = [2.0, 91.53, 16.7, 50.4]
y2 = [1240.3, 216.17, 310.77, 422.12, 513.53, 113.53, 377.249, 1179.41]
y3 = [15.6, 235.433, 574.45]

# save all months in a list
months = ['January',
          'February',
          'March',
          'April',
          'May',
          'June',
          'July',
          'August',
          'September',
          'October',
          'November',
          'December']

monthsDict = {}

# assign in a dictionary a number for each month
# 'January' : 0, 'February' : 1
for i, val in enumerate(months):
    monthsDict[val] = i


# this function converts the given datasets by you into full 12 months list
def to_full_list(x, y):

    # initialize a list of floats with a length of 12
    result = [0.0] * 12

    # assign for each months in the list the value to the corresponding index in result
    # x[0] = January, y[0] = 2.0 would be result[0] = 12.0
    for i, val in enumerate(x):
        result[monthsDict[val]] = y[i]

    return result


# convert the given data into the right format
r1 = np.array(to_full_list(x1, y1))
r2 = np.array(to_full_list(x2, y2))
r3 = np.array(to_full_list(x3, y3))

# increase the width of the output to match the long month strings
plt.figure(figsize=(11, 6))

# plot each of the created datasets
# x axis: months; y axis: values
p3 = plt.bar(months, r3 + r2 + r1)
p2 = plt.bar(months, r2 + r1)
p1 = plt.bar(months, r1)

# display the plot
plt.show()

【讨论】:

  • @William 12 月数据的唯一值是1179.41。我错过了什么重要的东西吗?我也刚刚意识到,您删除了另一个问题并创建了一个新问题。哎呀。
  • 谢谢 - 这部分是正确的,虽然在堆叠中似乎有错误
  • 12 月有 1179.41、574.45 和 50.4。 x1 中的月份直接映射到 y1。所以 x1 中的 12 月映射到 y1 中的 50.4
  • @William 抱歉,我忘了对 r1、r2 和 r3 的值求和。请稍等,我将编辑答案。
【解决方案2】:

将我的评论变成答案:不要拆分数据框,而是添加一个带有限定符的新列以堆叠(小、中、大)。然后以该新列为轴旋转框架并使用stacked=True 选项进行绘图。

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

# some data
dft = pd.DataFrame({"month" : ['January', 'October', 'November', 'December', 'January',
                               'June', 'July', 'August', 'September', 'October',
                               'November', 'December', 'January', 'November', 'December'],
                    "expediture" : [2.0, 91.53, 16.7, 50.4, 1240.3, 216.17, 310.77, 422.12,
                                    513.53, 113.53, 377.249, 1179.41, 156, 2354.33, 157.45]})

# possible labels / months
labels = ['small', 'medium', 'large']
months = pd.date_range('2014-01','2014-12', freq='MS').strftime("%B").tolist()
full = pd.DataFrame(columns=labels, index=months)

#quantize data
dft["quant"] = pd.cut(dft["expediture"], bins = [0,100,500,np.inf], labels=labels)
# pivot data
piv = dft.pivot(values='expediture',  columns="quant",  index = "month")
# update full with data to have all months/labels available, even if not
# present in original dataframe
full.update(piv)

full.plot.bar(stacked=True)

plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-24
    • 2018-05-09
    • 1970-01-01
    • 2020-11-03
    • 2018-11-26
    • 1970-01-01
    相关资源
    最近更新 更多