Python sqlite3和matplotlib绘制第一个图

时间:2017-07-24 12:23:28

标签: python matplotlib sqlite

我试图用matplotlib绘制我的第一个图表,我是sqlite3和matplotlib的新手,通常使用rrdtool。我没有填充数据库或检索(转储)数据库的问题,但我无法理解创建图表。你能否把我放在正确的路径上,在时间轴上为我的车库绘制一系列温度和湿度?

表的格式为:

create table external (temperature float, humidity float, feelslike float, timenow text);

使用数据库中的.dump提取的内容如下:

INSERT INTO "external" VALUES(17.0,68.0,11.6,'2017-07-24 12:24:02.578014');
INSERT INTO "external" VALUES(17.7,68.0,12.3,'2017-07-24 12:34:02.590939');
INSERT INTO "external" VALUES(17.7,68.0,12.3,'2017-07-24 12:44:02.585097');
INSERT INTO "external" VALUES(17.7,68.0,12.3,'2017-07-24 12:54:02.594123');
INSERT INTO "external" VALUES(18.3,63.0,12.8,'2017-07-24 13:04:02.586191');
INSERT INTO "external" VALUES(18.3,63.0,12.8,'2017-07-24 13:14:02.566619');

我的功能

import sqlite3
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
from matplotlib import style

def graph_data():
    # Connect to database
    now = datetime.now()
    sqlite_file = '/home/pi/scripts/database/climate.db'
    conn = sqlite3.connect(sqlite_file)
    c = conn.cursor()
    style.use('fivethirtyeight')

    c.execute('SELECT temperature, humidity, feelslike, timenow FROM external')
    data = c.fetchall()

    temperature = []
    humidity = []
    feelslike = []
    timenow = []

    for row in data:
        timenow.append(parser.parse(row[0]))
        values.append(row[1])

    plt.plot_date(temperature, humidity, feelslike,'-')
    plt.savefig('/home/pi/scripts/database/foo.png')
    c.close()
    conn.close()

我的代码产生以下错误:

Traceback (most recent call last):
  File "test.py", line 364, in <module>
    graph_data()
  File "test.py", line 323, in graph_data
    timenow.append(parser.parse(row[0]))
  File "/usr/local/lib/python2.7/dist-packages/dateutil/parser.py", line 1168, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/dateutil/parser.py", line 556, in parse
    res, skipped_tokens = self._parse(timestr, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/dateutil/parser.py", line 675, in _parse
    l = _timelex.split(timestr)         # Splits the timestr into tokens
  File "/usr/local/lib/python2.7/dist-packages/dateutil/parser.py", line 192, in split
    return list(cls(s))
  File "/usr/local/lib/python2.7/dist-packages/dateutil/parser.py", line 61, in __init__
    '{itype}'.format(itype=instream.__class__.__name__))
TypeError: Parser must be a string or character stream, not float

我猜它解析日期的方式?

1 个答案:

答案 0 :(得分:3)

你是正确的sqlite3.Cursor.fetchall()返回sqlite3.Row可映射/可迭代对象的一个​​(可能是空的)列表,你只是颠倒了顺序 - 你试图将温度字段解析为日期。 而且您的values变量未定义。

试试这个:

    c.execute('SELECT temperature, humidity, feelslike, timenow FROM external')
    data = c.fetchall()
    # data[*][0] = temperature
    # data[*][1] = humidity
    # data[*][2] = feelslike
    # data[*][3] = timenow

    temperature = []
    humidity = []
    feelslike = []
    timenow = []

    for row in data:
        temperature.append(row[0])
        humidity.append(row[1])
        feelslike.append(row[2])
        timenow.append(parser.parse(row[3]))

此外,由于Row除了按索引访问外,还支持按列名进行映射访问,您可以这样做:

    for row in data:
        temperature.append(row['temperature'])
        humidity.append(row['humidity'])
        feelslike.append(row['feelslike'])
        timenow.append(parser.parse(row['timenow']))

然而,索引访问速度更快,效率更高。

对于绘图,您需要多次调用plot,每次都使用相同的x和不同的y数据。为了测试,我用:

生成了我的数据集
    random.seed(0)
    data = [(random.uniform(10, 25),
             random.uniform(70, 99),
             random.uniform(15, 30),
             "2017-07-24 12:{:02d}:00.{:06d}".format(i, i * 1000 + int(random.uniform(0, 50)))
             ) for i in range(10)]

而不是使用数据库和data = c.fetchall()

现在您有一组float个数据点和关联的datetime.datetime个对象。但是,matplotlib.axes.Axes.plot_date函数接受:

  

x和/或y可以是表示为浮动天数的日期序列   0001-01-01 UTC。

要将日期从datetime.datetime对象转换为matplotlib的浮动天数,请使用函数matplotlib.dates.date2num

   for row in data:
       temperature.append(row[0])
       humidity.append(row[1])
       feelslike.append(row[2])
       timenow.append(parser.parse(row[3]))

   # Convert datetime.datetime to float days since 0001-01-01 UTC.
   dates = [date2num(t) for t in timenow]

   fig = plt.figure()
   ax1 = fig.add_subplot(111)
   ax1.set_title("My environmental data")

   # Configure x-ticks
   ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%Y %H:%M'))

   # Plot temperature data on left Y axis
   ax1.set_ylabel("Temperature [°C]")
   ax1.plot_date(dates, temperature, '-', label="Temperature", color='r')
   ax1.plot_date(dates, feelslike, '-', label="Feels like", color='b')

   # Plot humidity data on right Y axis
   ax2 = ax1.twinx()
   ax2.set_ylabel("Humidity [% RH]")
   ax2.plot_date(dates, humidity, '-', label="Humidity", color='g')

   # Format the x-axis for dates (label formatting, rotation)
   fig.autofmt_xdate(rotation=60)
   fig.tight_layout()

   # Show grids and legends
   ax1.grid(True)
   ax1.legend(loc='best', framealpha=0.5)
   ax2.legend(loc='best', framealpha=0.5)

   plt.savefig("figure.png")

此代码生成以下图像: enter image description here