我是matplotlib的新手,所以请原谅我的无知并帮助我解决这个问题。基本上我有一个CSV文件中的其他python脚本生成以下数据。
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值,每个Y值显示" data1"," data2"和" data3"分别。数据每10秒收集一次,但不一定是同步的。所以我不能为X轴提供单个阵列。但我希望所有这些都在同一个图表中进行比较。我怎么解决这个问题 ?
非常感谢任何示例代码或文档引导。
**编辑:
我的问题基本上是数据在不同的时间段内被指示,但我想在同一图上绘制它们。我该怎么做?**
编辑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个小时以上的数据点。因此,当我绘制时,我得到一个非常糟糕的图表。我如何解决它 ?但是,当我有少量数据时,我会得到一个合适的图表。
答案 0 :(得分:2)
好的,我更新了我的初步答案。这是一种可能的解决方案。但是既然你在谈论一个CSV文件,你可能想看看在Pandas中使用时间序列。
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()
答案 1 :(得分: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_stamps
是一个datetime
对象,我假设您只需要基于样本数据的小时:分钟:秒。我们可以通过一个列表理解轻松实现这一点:
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
plt.xticks(np.arange(number_seconds), time_stamps_fmt)