3

我正在绘制一个天气数据的 CSV 文件,并且在我的代码中可以很好地导入它,但我正在尝试绘制它。以下是 CSV 数据的示例:

12:00am,171,6,7,52,76,77.1,63.7,28.74,0.00,0.00,0.0,0,63.7,78.1,67.4,56.0,29.96
12:01am,192,4,6,52,76,77.1,63.7,28.74,0.00,0.00,0.0,0,63.7,78.1,67.4,56.0,29.96
12:02am,197,3,6,52,76,77.1,63.7,28.74,0.00,0.00,0.0,0,63.7,78.1,67.4,56.0,29.96
12:03am,175,3,6,52,76,77.1,63.7,28.73,0.00,0.00,0.0,0,63.7,78.1,67.4,56.0,29.96
12:04am,194,4,6,52,76,77.1,63.7,28.73,0.00,0.00,0.0,0,63.7,78.1,67.4,56.0,29.96
12:05am,148,5,6,52,76,77.1,63.7,28.73,0.00,0.00,0.0,0,63.7,78.1,67.4,56.0,29.96

无论如何,我希望时间在 X 轴上,但我无法使用 matplotlib 进行绘图。我尝试了一种使用 xticks 的方法,它绘制了我的 y 值,但仅此而已。它只是在我的 X 轴上给了我一条粗实线。

import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
from matplotlib.dates import date2num
import datetime as DT
import re

data = np.genfromtxt('FILE.csv', delimiter=',', dtype=None, skip_header=3)
length = len(data)

x = data['f0']
y = data['f7']

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_title("Temperature")    
ax1.set_xlabel('Time')
ax1.set_ylabel('Degrees')


#plt.plot_date(x, y)
plt.show()
leg = ax1.legend()

plt.show()

我错过了一些关键部分,因为我真的不知道从这里去哪里。我检查了我的 numpy 数组的数据类型,它一直说 numpy.ndarray,我找不到将其转换为字符串或 int 值的方法来绘制。这是一个 24 小时 CSV 文件,我希望每 30 分钟左右打一个刻度线。有任何想法吗?

4

2 回答 2

1

pandas是一个非常有用的时间序列分析库,具有一些基于 matplotlib 的绘图功能。

Pandasdateutil在内部使用来解析日期,但问题是日期不包含在您的文件中。在下面的代码中,我假设您会在解析文件之前知道日期(从文件名?)

In [125]: import pandas as pd
In [126]: pd.options.display.mpl_style = 'default'
In [127]: import matplotlib.pyplot as plt

In [128]: class DateParser():                                          
   .....:     def __init__(self, datestring):
   .....:         self.datestring = datestring
   .....:     def get_datetime(self, time):    
   .....:         return dateutil.parser.parse(' '.join([self.datestring, time]))
   .....:     

In [129]: dp = DateParser('2013-01-01')

In [130]: df = pd.read_csv('weather_data.csv', sep=',', index_col=0, header=None,
                  parse_dates={'datetime':[0]}, date_parser=dp.get_datetime)

In [131]: df.ix[:, :12] # show the first columns
Out[131]: 
                      1   2   3   4   5     6     7      8   9   10  11  12  
datetime                                                                      
2013-01-01 00:00:00  171   6   7  52  76  77.1  63.7  28.74   0   0   0   0   
2013-01-01 00:01:00  192   4   6  52  76  77.1  63.7  28.74   0   0   0   0   
2013-01-01 00:02:00  197   3   6  52  76  77.1  63.7  28.74   0   0   0   0   
2013-01-01 00:03:00  175   3   6  52  76  77.1  63.7  28.73   0   0   0   0   
2013-01-01 00:04:00  194   4   6  52  76  77.1  63.7  28.73   0   0   0   0   
2013-01-01 00:05:00  148   5   6  52  76  77.1  63.7  28.73   0   0   0   0   

In [132]: ax = df.ix[:,1:3].plot(secondary_y=1)

In [133]: ax.margins(0.04)

In [134]: plt.tight_layout()

In [135]: plt.savefig('weather_data.png')

天气数据.png

于 2013-07-05T06:01:22.037 回答
1

好吧,这不是很优雅,但它确实有效。关键是将存储在 中的时间(x只是字符串)更改为 datetime 对象,以便 matploblib 可以绘制它们。我做了一个函数来进行转换并调用它get_datetime_from_string

** 编辑后的代码与 Python 2.7 兼容,并使用单位数小时的时间 **

import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
from matplotlib.dates import date2num
import datetime as DT
import re

def get_datetime_from_string(time_string):
    ''' Returns a datetime.datetime object

        Args
        time_string: a string of the form 'xx:xxam'
        '''

    # there's got to be a better way to do this.
    # Convert it to utf-8 so string slicing works as expected.
    time_string = unicode(time_string, 'utf-8')

    # period is either am or pm
    colon_position = time_string.find(':')
    period = time_string[-2:]
    hour = int(time_string[:colon_position])
    if period.lower() == 'pm':
        hour += 12

    minute = int(time_string[colon_position + 1:colon_position + 3])

    return DT.datetime(1,1,1,hour, minute)

data = np.genfromtxt('test.csv', delimiter=',', dtype=None, skip_header=3)
length=len(data)

x=data['f0']
y=data['f7']

datetimes = [get_datetime_from_string(t) for t in x]

fig = plt.figure()

ax1 = fig.add_subplot(111)

ax1.set_title("Temperature")    
ax1.set_xlabel('Time')
ax1.set_ylabel('Degrees')

plt.plot(datetimes, y)
leg = ax1.legend()

plt.show()

我一直被绊倒,因为我time_string在将其转换为utf-8. 在它给我ASCII值或其他东西之前。我不确定为什么转换它会有所帮助,但确实如此。

于 2013-07-04T21:33:55.680 回答