Matplotlib x Axis时间错误

时间:2017-11-02 13:23:12

标签: python matplotlib

我有一些由前工程师编写的Python代码,我正在尝试添加它。该脚本记录串行字符串输入的值,并将字符串中的值记录在CSV文件中。 CSV文件显示如下

12h35m15s,0.01t
12h35m16s,0.02t
12h35m17s,0.05t
12h35m18s,0.15t
12h35m19s,0.21t
12h35m20s,0.23t
12h35m21s,0.20t
12h35m22s,0.21t
12h35m23s,0.22t
12h35m24s,0.26t

依旧......

我所做的是在代码中添加了一个部分,这样当您按下按钮时,它会使用matplotlib生成CSV文件中的数据图表。

我遇到的问题是matplotlib无法以12h25m15s的格式绘制时间,因为它不是浮点数。我已经更改了代码以从CSV文件中删除h,m和s,但问题是秒值。 1秒的秒数是1秒,而不是01秒,因此我的图表值将是例如:

12358  (at 12h25m8s)
12359  (at 12h25m9s)
123510 (at 12h25m10s)
123511 (at 12h25m11s)
123512 (at 12h25m12s)
123513 (at 12h25m13s)

然后到12h36m

12361  (at 12h36m1s)
12362  (at 12h36m2s)

依旧......

这意味着当绘制我的图表时,它会将12h36m1s视为低于12h35m10s的值,并将数据混合到图表中的数据。

我需要找到两种解决方案之一:

1)更正时间格式,以便matplotlib正确绘制时间 2)将我的x轴值设置为要绘制的数据记录的数量。即如果我有y的50个数据记录,我的x轴只是1-50而不是时间。

有人可以为此提供帮助吗?

我的图表代码是:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime as dt
import numpy as np

s = open('log0.csv','r').read()

CSVunits = ('kN', 'T', 'lb', 'kg', 't') 
for c in CSVunits:
    s = ''.join( s.split(c) )

out_file = open('graph.csv','w')
out_file.write(s)
out_file.close()

data = [['13h10m5s'],['13h20m5s'],['13h30m5s'],['13h40m5s'],['13h50m5s'],['14h0m5s']]
#data = np.loadtxt('graph.csv', delimiter=',', skiprows=4,usecols=[0])
x = [mdates.date2num(dt.datetime.strptime(x[0], '%Hh%Mm%Ss')) for x in data]
y = np.loadtxt('graph.csv', delimiter=',', skiprows=4,usecols=[1])

fig,ax = plt.subplots(1)

ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
ax.plot_date(x, y, '-') # '-' adds the line on the graph joining points

plt.xlabel('Time')
plt.ylabel('Load Value')
plt.title('Graph Showing Load Against Time\n')

plt.show()

当我运行时,我收到错误:

ValueError:float()的文字无效:12h35m15s

为了清楚起见,在我的数据示例中,1,2和3只是为了表示CSV文件中的行,没有列或数据包含1,2和3.它只是时间和浮点值我有我的CSV。

由于

2 个答案:

答案 0 :(得分:1)

想象一下您的数据看起来像

1   12h35m8s    0.02
2   12h35m9s    0.04
3   12h35m10s   0.06
4   12h35m11s   0.07
5   12h35m12s   0.08
6   12h35m13s   0.06
7   12h35m15s   0.05
8   12h35m16s   0.02
9   12h35m17s   0.03
10  12h36m1s    0.04
11  12h36m2s    0.03

您可以在via pandas中阅读并直接绘制它,

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("data/timetable2.txt", delim_whitespace=True, header=None, 
                 names=["time","quantitiy"], index_col=0)
df["time"] = pd.to_datetime(df["time"], format="%Hh%Mm%Ss")

df.set_index("time").plot()

plt.show()

enter image description here

您也可以使用matplotlib来更好地控制时间的表示方式(例如,您可以在轴上使用原始格式"%Hh%Mm%Ss"。)

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates

df = pd.read_csv("data/timetable2.txt", delim_whitespace=True, header=None, 
                 names=["time","quantity"], index_col=0)
df["time"] = pd.to_datetime(df["time"], format="%Hh%Mm%Ss")

plt.plot(df["time"],df["quantity"])
plt.gca().xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%Hh%Mm%Ss"))

plt.show()

enter image description here

答案 1 :(得分:1)

推荐@ImportanceOfBeingErnest回答(pandas是一个很棒的工具)。但是既然我已经开始了它,我会抛出另一种可能的方法。这是一个简化的例子(因此重要的位很明显)。而且,我认为你自己比你需要的更难。

更新2:根据OP对问题的修订,以下是使用新源数据的工作示例。我已经将数据格式化为多行,以便更容易看到正在发生的事情。我更改了x_labels行,以反映观察编号不在最初发布的源数据中。

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime as dt

with open('test.csv', 'r') as f:
    data = f.readlines()
    # ['12h35m15s,0.01t\n', '12h35m16s,0.02t\n', '12h35m17s,0.05t\n', '12h35m18s,0.15t\n', '12h35m19s,0.21t\n', '12h35m20s,0.23t\n', '12h35m21s,0.20t\n', '12h35m22s,0.21t\n', '12h35m23s,0.22t\n', '12h35m24s,0.26t']

data_to_plot = [[d.strip('t\n')] for d in data]  # Split the lines into lists and strip the 't' and new line
# [['12h35m15s,0.01'], ['12h35m16s,0.02'], ['12h35m17s,0.05'], ['12h35m18s,0.15'], ['12h35m19s,0.21'], ['12h35m20s,0.23'], ['12h35m21s,0.20'], ['12h35m22s,0.21'], ['12h35m23s,0.22'], ['12h35m24s,0.26']]

data_to_plot = [d[0].split(',') for d in data_to_plot]  # Break each observation into separate strings
# [['12h35m15s', '0.01'], ['12h35m16s', '0.02'], ['12h35m17s', '0.05'], ['12h35m18s', '0.15'], ['12h35m19s', '0.21'], ['12h35m20s', '0.23'], ['12h35m21s', '0.20'], ['12h35m22s', '0.21'], ['12h35m23s', '0.22'], ['12h35m24s', '0.26']]

x = [mdates.date2num(dt.datetime.strptime(x[0], '%Hh%Mm%Ss')) for x in data_to_plot] 
y = [y[1] for y in data_to_plot]

x_labels = [n for n in range(1, len(data_to_plot) + 1)]

fig,ax = plt.subplots(1)

ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))

ax.plot_date(x, y, '-')

plt.xticks(x, x_labels)

plt.show()

重要提示: 除非确保源数据时间戳都符合##h##m##s格式,否则Update 2示例仍然无效。否则,我们需要添加一些额外的代码以使它们统一。

enter image description here

[为清楚起见,先前的答案已删除。请参阅修订历史记录以查看问题的先前答案。]