2014-07-17 66 views
0

我是matplotlib的新手,请原谅我的无知并帮我解决这个问题。本质上,我有一个CSV文件中的其他Python脚本正在生成以下数据。针对同一图形中matplotlib中不同时间戳的多个X值绘制多个Y值?

CSV1: 时间戳,DATA1

23:04:17, 1163557.14 bps 
23:04:27, 1137578.47 bps 
23:04:37, 1139094.66 bps 
23:04:47, 1095752.97 bps 
23:04:57, 1264145.01 bps 

CSV2: 时间戳,DATA2

23:04:21, 1011000.00 bps 
23:04:31, 1011000.00 bps 
23:04:41, 1011000.00 bps 
23:04:51, 1014000.00 bps 
23:05:01, 1008000.00 bps 

CSV3: 时间戳,DATA3

23:05:28, 1109617.96 bps 
23:05:38, 1139177.95 bps 
23:05:48, 1108110.09 bps 
23:05:58, 1107078.94 bps 
23:06:08, 1163406.80 bps 

我想要的是沿X轴有时间运行,沿Y轴有三个Y值,分别显示“data1”,“data2”和“data3”。数据每10秒收集一次,但不一定同步。所以我不能有一个单一的X轴阵列。但我希望所有这些在同一个图表中进行比较。我怎么解决这个问题 ?

任何示例代码或导致文档将不胜感激。

**编辑:

基本上我的问题是,数据被索引沿不同的时戳,但我要绘制THEM在同一图表上。我该怎么做**

编辑2:

谢谢你们为输入。这真的有帮助。因此,这是代码我现在有:

import csv 
    import sys 
    import datetime 
    import random 
    import matplotlib.pyplot as plt 
    from matplotlib.dates import MinuteLocator, SecondLocator, DateFormatter 

    time_e_z_raw_list = [] 
    bitrate_e_z_list = [] 
    time_i_z_raw_list = [] 
    bitrate_i_z_list = [] 
    time_i_query_z_raw_list = [] 
    bitrate_i_q_z_raw_list = [] 

    f_enc_z = open(sys.argv[1], 'rt') 
    f_ing_z = open(sys.argv[2], 'rt') 
    f_ing_q_z = open(sys.argv[3], 'rt') 

    try: 
     reader1 = csv.reader(f_enc_z) 
     for row in reader1: 
      bitrate = row[1] 
      time_e_z_raw_list.append(row[0]) 
      bitrate_e_z_list.append(bitrate[:-4]) 
     reader3 = csv.reader(f_ing_z) 
     for row in reader3: 
      bitrate = row[1] 
      time_i_z_raw_list.append(row[0]) 
      bitrate_i_z_list.append(bitrate[:-4]) 
     reader4 = csv.reader(f_ing_q_z) 
     for row in reader4: 
      bitrate = row[1] 
      time_i_q_z_raw_list.append(row[0]) 
      bitrate_i_q_z_raw_list.append(bitrate[:-4]) 

    finally: 
     f_enc_z.close() 
     f_ing_z.close() 
     f_ing_q_z.close() 

    time_e_z_list = [datetime.datetime.strptime(s, '%H:%M:%S') for s in   time_e_z_raw_list] 
    time_i_z_list = [datetime.datetime.strptime(s, '%H:%M:%S') for s in  time_i_z_raw_list] 
    time_i_q_z_list = [datetime.datetime.strptime(s, '%H:%M:%S') for s in time_i_q_z_raw_list] 

    fig = plt.figure(figsize=(18,16)) 

    plt.plot(time_e_z_list, bitrate_e_z_list, label="label1", lw=1) 
    plt.plot(time_i_z_list, bitrate_i_z_list, label="label2", lw=1) 
    plt.plot(time_i_q_z_list, bitrate_i_z_list, label="label3", lw=1) 

    minutes = MinuteLocator() 
    seconds = SecondLocator() 

    ax = plt.gca() 
    ax.xaxis.set_major_locator(minutes) 
    ax.xaxis.set_minor_locator(seconds) 
    ax.xaxis.set_major_formatter(DateFormatter("%H:%M:%S")) 
    plt.xlabel('time') 
    plt.ylabel('bitrate in bps') 
    plt.grid() 
    plt.legend(loc='upper right') 

    plt.gcf().autofmt_xdate() 

    plt.show() 

麻烦的是,当我有一个范围超过3小时以上的时间戳,图形被扭曲得到。我如何确保X轴显示的范围根据我采样的时间戳范围动态调整?通常,我每20秒运行4个小时以上的数据点。所以,当我绘制我得到一个非常糟糕的图。我如何解决它 ?但是,当我有少量数据时,我会得到一个适当的图表。

回答

2

好吧,我更新了我最初的答案。这是一个可能的解决方案。但是既然你在谈论一个CSV文件,你可能想看看熊猫的时间系列。

import datetime 
import random 
import matplotlib.pyplot as plt 

data1 = (1163557.14, 1137578.47, 1139094.66) 
times1_raw = ('23:04:17', '23:04:27', '23:04:37') 
times1 = [datetime.datetime.strptime(s, '%H:%M:%S') for s in times1_raw] 

data2 = (1011000.00, 1011000.00, 1011000.00) 
times2_raw = ('23:04:21', '23:04:31', '23:04:41') 
times2 = [datetime.datetime.strptime(s, '%H:%M:%S') for s in times2_raw] 

fig = plt.figure(figsize=(8,6)) 

plt.plot(times1, data1, label='data1', lw=2, marker='o') 
plt.plot(times2, data2, label='data2', lw=2, marker='s') 
plt.xlabel('time in seconds') 
plt.ylabel('speed in bps') 
plt.grid() 
plt.legend(loc='upper right') 

plt.gcf().autofmt_xdate() 

plt.show() 

enter image description here

+0

我会非常想拥有完整的时间戳太。所以我希望时间戳沿着X轴运行。只要data1和data2的数据点关闭几秒钟。是否有可能在X轴上有时间戳? – rajath26

+0

很高兴听到。也许你可以提供一些图像来显示这个问题实际上看起来如何 – Sebastian

0

这是我会怎么解决这个问题。

首先,尝试利用datetime模块。处理带时间戳的数据时可以节省时间。

我们知道时间步长的最小增量是一秒。所以我们首先制作一个包含所有可能时间的列表。

import matplotlib.pyplot as plt 
import datetime 

start_date = datetime.datetime(2014,6,17,23,4,17) 
end_date = datetime.datetime(2014,6,17,23,6,8) 
number_seconds = (end_date - start_date).seconds 

time_stamps = [start_date + datetime.timedelta(seconds=t) for t in range(number_seconds)] 

现在列表time_stampsdatetime对象,我想你只想小时:分钟:基于您的样本数据邮票第二。我们可以很容易地与一个以上列表理解:

time_stamps_fmt = [datetime.datetime.strftime(t,'%H:%m:%S') for t in time_stamps] 

现在,让我们创建一个空数组存储bps的数据:

bps_1 = np.zeros([number_seconds],dtype('float')) 
bps_2 = np.zeros([number_seconds],dtype('float')) 
bps_3 = np.zeros([number_seconds],dtype('float')) 

然后填充的bps_1/2/3对应的指数在时间戳。 csv文件。如果未找到时间戳,请为该索引插入np.nan,matplotlib应将其视为缺失值并且不绘制任何内容。

可以使用xticks显示时间标记为x-标签:

plt.xticks(np.arange(number_seconds), time_stamps_fmt) 
+0

这是一个有趣的方式,你建议@ N1B4。但是如果我运行了4个多小时,你认为通过索引每秒会有所帮助吗? – rajath26

+0

您必须至少以一秒为间隔存储数据,因为这是包含所有数据的最小频率。但是你需要绘制每个数据点吗?分钟平均值如何?还是10分钟的平均水平? – N1B4

相关问题