【问题标题】:plot stacked bar chart from csv file using python使用python从csv文件绘制堆积条形图
【发布时间】:2015-07-15 14:28:06
【问题描述】:

我有一个 csv 文件中的数据,如下所示:

,jobID,hum_starttime,hum_endtime,duration,exit_status,CPU,energy,memory,virt_mem,wall_time
0,525231,29/05/2015 11:53:47,29/05/2015 14:09:16,8129.0,0.0,28:54:56,0,4682480kb,16036608kb,01:13:59
1,504231,08/05/2015 07:46:59,08/05/2015 07:48:55,116.0,0.0,00:00:49,0,2421756kb,2807020kb,00:00:51

我想以 1 小时为单位绘制 exit_status 计数(即 exit_status == 1exit_status == -11 的次数)与 start_time 的比较。由于有几个不同的exit_status 代码,我需要以stacked bar chart 的形式绘制它,其中每个不同的退出状态都被赋予不同的颜色。

谁能帮帮我?我已经坚持了2天了!!谢谢!

【问题讨论】:

  • csv.readercsv.DictReader 很可能是您的朋友。你可能还想要datetime
  • 您坚持哪一部分,阅读和分析数据,或者使用 matplotlib 从中创建条形图?如果您在两个问题上都遇到问题,可能会更好地将您的问题分成两个单独的问题。

标签: python csv plot bar-chart stacked-chart


【解决方案1】:

以下是我的解决方法:

  1. 读取 csv 文件。这可以使用 python 的csv 模块来完成
  2. 根据您的 bin 大小读取和/或转换日期戳,并遍历每一行,添加到正确的小时 bin。我只是用肮脏的方式来减少分钟和秒数:row[0][:-5] 返回15/07/2015 11,一个日期和小时。

你最终会得到一个列表status_records,它由两个字典组成,代表两个状态选项,然后包含小时箱:

  • "1" : {"15/07/2015 11": 3, ...}
  • "-11" : {"15/07/2015 11": 0, ...}

这是一个示例data.csv,其中包含更多数据(这样您就可以真正看到一些东西,这对于您的 2 个条目来说很难 - 我使用相同的日期格式和状态代码你提到):

start_time,exit_status
15/07/2015 11:53:47,1
15/07/2015 11:53:47,1
15/07/2015 11:54:56,1
15/07/2015 12:23:26,-11
15/07/2015 12:27:31,1
15/07/2015 14:01:47,-11
15/07/2015 14:11:56,1
15/07/2015 14:52:47,1
15/07/2015 15:53:23,1
15/07/2015 15:55:11,1

这是我的代码(您必须将 row[0] 等更改为相应的行才能使用您的 csv):

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import csv

# 1. reading the csv
status_records = {'1': {}, '-11': {}}

with open('data.csv', 'rb') as csvfile:
    reader = csv.reader(csvfile)
    # 2. iterate through csv
    for row in reader:
        if row[0] == 'start_time': continue # first line
        hour = row[0][:-5]
        status = row[1]

        # if hour not present, add empty 'slot' in each status bin
        if hour not in status_records[status].keys():
            status_records['1'][hour] = 0
            status_records['-11'][hour] = 0
            status_records[status][hour] = 1 # add the status we just read
        else:
            status_records[status][hour] += 1 # update status-hour bin

status1   = status_records['1'].values()
status2 = status_records['-11'].values()

print status1, status2

N = len(status1)
ind = np.arange(N)
width = 0.35

p1 = plt.bar(ind, status1, width, color='g')
p2 = plt.bar(ind, status2, width, color='r', bottom=status1)

plt.ylabel('# of exit status')
plt.title('Exit status in comparison with time')
plt.yticks(np.arange(0,11,10))
plt.legend((p1[0], p2[0]), ('1', '-11'))
plt.show()

输出:

改进:您可能想要添加一些有用的标签,并决定是否显示没有发生任何事情的时间(这可能会使图表变得混乱)。另外,请注意,日期应按原样在 csv 中排序,否则您必须自己在代码中对其进行排序。

无论如何,这应该给你一些开始。

【讨论】:

  • 嘿,adrianus 非常感谢,这真的很有帮助。我很感激...我的下一个问题:P 我实际上有很多不同的 exit_status'(-12、-11、... 0、1、2、...、271 等),我需要修改代码这样我在你的第二个 if 语句中有一个 for 循环和一个 for 循环,它绘制所有不同的 exit_status' 并为每个不同的 exit_status 分配一个唯一的颜色。你能帮帮我吗?再次感谢! (另外,这是额外的,所以不要担心它是否太多,我想将所有数据标准化为 1。即 #number of exit status' 的最大值应为 1)
  • 我们谈论多少不同的状态码?超过271?使用matplotlib.colors,您可以通过 rgb 或 Hex 代码生成颜色。如果你只有,比如说十几个代码,只需像 status_colors = {'-12': 'r', '-11': 'y', '0': 'r', ...} 一样创建一个 dict 并像 color = status_colors[status] 一样使用它
  • 对于规范化部分:只需循环遍历每个状态,遍历每个 bin,对项目求和,然后将每个 bin 除以该总和。
  • 很酷,谢谢。是的,实际上有超过 300 个状态码,所以我需要一个 for 循环
  • 也许您想将状态代码分类为不同的类别,每个类别都有一个颜色? 300 种颜色的图表很难阅读 :-) 不客气,如果对您有帮助,请考虑将其作为公认的答案。
猜你喜欢
  • 2018-03-10
  • 2012-09-17
  • 2021-12-27
  • 2017-04-11
  • 2016-05-24
  • 2021-01-01
相关资源
最近更新 更多