Python sqlite3和matplotlib绘制第一个图形

Python sqlite3和matplotlib绘制第一个图形,python,matplotlib,sqlite,Python,Matplotlib,Sqlite,我正在尝试使用matplotlib绘制我的第一个图形,我不熟悉sqlite3和matplotlib,通常使用rrdtool。我在填充数据库或检索(转储)数据库方面没有问题,但我无法专心创建图形。你能让我在时间轴上画出车库的温度和湿度系列图吗 表格格式如下: create table external (temperature float, humidity float, feelslike float, timenow text); 使用.dump从数据库中提取的内容如下所示: INSERT

我正在尝试使用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
回溯(最近一次呼叫最后一次):
文件“test.py”,第364行,在
图_数据()
图形_数据中第323行的文件“test.py”
timenow.append(parser.parse(行[0]))
文件“/usr/local/lib/python2.7/dist packages/dateutil/parser.py”,第1168行,在parse中
返回DEFAULTPARSER.parse(timestr,**kwargs)
文件“/usr/local/lib/python2.7/dist packages/dateutil/parser.py”,第556行,在parse中
res,跳过的令牌=self.\u解析(timestr,**kwargs)
文件“/usr/local/lib/python2.7/dist packages/dateutil/parser.py”,第675行,在
l=_timelex.split(timestr)#将timestr拆分为令牌
文件“/usr/local/lib/python2.7/dist-packages/dateutil/parser.py”,第192行,拆分
退货清单(cls)
文件“/usr/local/lib/python2.7/dist packages/dateutil/parser.py”,第61行,在__
“{itype}”。格式(itype=instream.\uuuuuu class.\uuuuuu name.\uuuuuu))
TypeError:分析器必须是字符串或字符流,而不是浮点
我猜是它解析日期的方式吗?

如果返回一个(可能是空的)可映射/可映射对象列表,则是正确的,您只是颠倒了顺序-尝试将温度场解析为日期。 您的
变量未定义

试试这个:

    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]))
此外,由于
除了按索引访问还支持按列名映射访问,您可以执行以下操作:

    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\u date函数接受:

x和/或y可以是一系列日期,表示为自 0001-01-01 UTC

要将matplotlib的日期从对象
datetime.datetime
转换为浮动天数,请使用函数
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")
此代码生成以下图像:

返回可映射/可编辑对象列表(可能为空)是正确的,您只是颠倒了顺序-尝试将温度场解析为日期。 您的
变量未定义

试试这个:

    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]))
此外,由于
除了按索引访问还支持按列名映射访问,您可以执行以下操作:

    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\u date函数接受:

x和/或y可以是一系列日期,表示为自 0001-01-01 UTC

要将matplotlib的日期从对象
datetime.datetime
转换为浮动天数,请使用函数
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")
此代码生成以下图像:

这很有效!我如何用多个数据在一个时间轴上绘制这些数据呢?这显然是失败的:
plt.plt\u日期(温度、湿度、感觉像“-”)
谢谢你的提醒,我确实忽略了这句话。我编辑了答案并添加了绘图示例。同样,这非常有效,正是我想要给我的工作图,我现在可以从中学习、构建和调整。这很有效!我如何用多个数据在一个时间轴上绘制这些数据呢?这显然是失败的:
plt.plt\u日期(温度、湿度、感觉像“-”)
谢谢你的提醒,我确实忽略了这句话。我编辑了答案并添加了绘图示例。同样,这非常有效,也正是我想要给我的工作图,我现在可以从中学习、构建和调整。