huggies15
Posts: 9
Joined: Tue Feb 19, 2013 11:36 am

Basic graphing module/idea help

Tue Feb 19, 2013 11:46 am

Hi All,

I'm trying to get into programming (basic python programming) and have a problem.
I'm going to make a temperature sensor to record the time taken to boil some water etc.
Following the tutorial on the cambridge uni website (http://www.cl.cam.ac.uk/freshers/raspbe ... mperature/), I will end up (i think) with a file with a string of times and temperature.
What I want to do is have this data automatically converted to a simple graph and saved as an image, so i can print off both the raw data and a pretty graph.

What I dont know, is how to go about converting this data into a graph format, or what python modules are available and recommended to do this. I know I could load it into excel and do it manually, but I'm hoping to be creating 10s of these a day so dont want my time to be wasted doing that!

A basic idea of the setup (if it helps) is this: Headless RPi connected to the network, gathering data that i will store on a samba share on the Pi itself and hopefully then copy to a backup server daily. There is a printer on my main pc so the image(s) will be printed off manually at the end of each day.

Any help would be awesome, as i said, Im only starting to get to grips with how this works, and at the ripe old age of 26 my brain has already started to slow down on learning new things!

Cheers,
Steve

User avatar
scruss
Posts: 3212
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: Basic graphing module/idea help

Tue Feb 19, 2013 12:50 pm

It might be overkill, but matplotlib is used everywhere for this. Alternatively (and even more mature) you could pipe the data to gnuplot.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.
Pronouns: he/him

User avatar
davef21370
Posts: 897
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Re: Basic graphing module/idea help

Tue Feb 19, 2013 6:29 pm

Or plot the data to a picture using PIL (Python Imaging Library) or PyGame, then save them out as jpeg, png, etc. Quick and easy.

Dave.
Apple say... Monkey do !!

huggies15
Posts: 9
Joined: Tue Feb 19, 2013 11:36 am

Re: Basic graphing module/idea help

Wed Feb 20, 2013 3:23 pm

Hi, Thanks for getting back to me.
I've decided to go down the python + gnuplot route.
Below is the code ive written.
Im still waiting for my Pi to test it on, but if you could have a quick scan and see if it looks correct I would be grateful.
Because I cannot work out how to get gnuplot to open the most recent file created i have (i think) made the program output my data as two files - gnu.log and tempTIMESTAMP.log - temp will be kept and gnu.log will be overwritten constantly.
I have then got gnuplot to open the gnu.log file, output the data to gnu.png and then called the original python script to copy this file to graphTIMSTAMP.png so that the time stamps match and it can make new graphs without overwriting the original data...
Or at least that the plan.
Again, any advice would we heard gratefully,
Steve

Python:

Code: Select all

# Copyright (c) 2012 Matthew Kirk
# Licensed under MIT License, see 
# http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/temperature/LICENSE

import RPi.GPIO as GPIO
import time

LED1_GPIO_PIN = 18
LED2_GPIO_PIN = 25
BUTTON_GPIO_PIN = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_GPIO_PIN, GPIO.IN)
GPIO.setup(LED1_GPIO_PIN, GPIO.OUT)
GPIO.setup(LED2_GPIO_PIN, GPIO.OUT)

GPIO.output(LED1_GPIO_PIN, GPIO.HIGH)

while True:
	if GPIO.input(BUTTON_GPIO_PIN):
		break

while GPIO.input(BUTTON_GPIO_PIN):
	pass

GPIO.output(LED1_GPIO_PIN, GPIO.LOW)
GPIO.output(LED2_GPIO_PIN, GPIO.HIGH)

timestamp = time.strftime("%Y-%m-%d-%H-%M-%S")
prog_start = time.time()
filename = "".join(["temperaturedata", timestamp, ".log"])
image = "".join(["graph", timestamp, ".png"])
datafile = open(filename, "w", 1)
gnu = open("gnu.log", "w", 1)

measurement_wait = 15
button_pressed = False
while True:
	time_1 = time.time()
	tfile = open("/sys/bus/w1/devices/10-000802824e58/w1_slave")
	text = tfile.read()
	tfile.close()
	temperature_data = text.split()[-1]
	temperature = float(temperature_data[2:])
	temperature = temperature / 1000
	datafile.write(str(time.time()-prog_start) + "\t" + str(temperature) + "\n")
	gnu.write(str(time.time()-prog_start) + "\t" + str(temperature) + "\n")
	time_2 = time.time()
	if (time_2 - time_1) < measurement_wait:
		no_of_sleeps = int(round((measurement_wait - (time_2 - time_1)) / 0.1))
		for i in range(no_of_sleeps):
			time.sleep(0.1)
			if GPIO.input(BUTTON_GPIO_PIN):
				button_pressed = True
				break
	if button_pressed:
		break
			

datafile.close()
gnu.close()

import os
os.system("gnuplot temp.plt")

import shutil
shutil.copy(gnu.png, image)

GPIO.output(LED2_GPIO_PIN, GPIO.LOW)
GNUplot:

Code: Select all

set terminal png small size 900, 968 transparent# x000000
set output "gnu.png"
set time
set y2tics
set timestamp "%a %b %Y %H:%M:%S" bottom
set title "Temperature Profile" # 0.000000,0.000000  "";
set ylabel "Degrees Centigrade" # 0.000000,0.000000  ""
set xlabel "Time (seconds)"
set key below
plot 'gnu.log' using 1:2 with linespoints,\
set output

huggies15
Posts: 9
Joined: Tue Feb 19, 2013 11:36 am

Re: Basic graphing module/idea help

Wed Feb 20, 2013 4:28 pm

Or could i use matplotlib like so:

Code: Select all

# Copyright (c) 2012 Matthew Kirk
# Licensed under MIT License, see 
# http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/temperature/LICENSE

#import all neccessary modules
import RPi.GPIO as GPIO
import time
from pylab import *

#state pin setup
LED1_GPIO_PIN = 18
LED2_GPIO_PIN = 25
BUTTON_GPIO_PIN = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_GPIO_PIN, GPIO.IN)
GPIO.setup(LED1_GPIO_PIN, GPIO.OUT)
GPIO.setup(LED2_GPIO_PIN, GPIO.OUT)

#turn on LED
GPIO.output(LED1_GPIO_PIN, GPIO.HIGH)

#Search for button press
while True:
	if GPIO.input(BUTTON_GPIO_PIN):
		break

while GPIO.input(BUTTON_GPIO_PIN):
	pass

#Turn down led, light up 'processing' led
GPIO.output(LED1_GPIO_PIN, GPIO.LOW)
GPIO.output(LED2_GPIO_PIN, GPIO.HIGH)

#create file with timestamp and write to it
timestamp = time.strftime("%Y-%m-%d-%H-%M-%S")
prog_start = time.time()
filename = "".join(["temperaturedata", timestamp, ".log"])
graphname = "".join(["temperaturedata", timestamp, ".png"])
datafile = open(filename, "w", 1)

#measure every 15 seconds
measurement_wait = 15
button_pressed = False

#CREATE & GATHER DATAFILE
#check for end button press and gather data
while True:
	time_1 = time.time()
	tfile = open("/sys/bus/w1/devices/10-000802824e58/w1_slave")
	text = tfile.read()
	tfile.close()
	temperature_data = text.split()[-1]
	temperature = float(temperature_data[2:])
	temperature = temperature / 1000
	datafile.write(str(time.time()-prog_start) + "\t" + str(temperature) + "\n")
	time_2 = time.time()
	if (time_2 - time_1) < measurement_wait:
		no_of_sleeps = int(round((measurement_wait - (time_2 - time_1)) / 0.1))
		for i in range(no_of_sleeps):
			time.sleep(0.1)
			if GPIO.input(BUTTON_GPIO_PIN):
				button_pressed = True
				break
	if button_pressed:
		break
			
#close and save datafile
datafile.close()

#CREATE GRAPH
#create time and temp functions
time = {}
temp = {}

#open file created above
with open(filename, 'r') as f:
	lines = f.readlines()

#state what data is from which tab
	for line in lines:
		time = line.split('%t')[0].strip()
		temp = line.split('%t')[1].strip()

#plot line graph of time (x) vs temp (y)
plot(time, temp, color='red', linewidth=2.0, linestyle="-")
title('Time taken to boil 500 ml water', verticalalignment='top', fontsize=12, weight='bold')
xticks
xlabel('Time (s)', fontsize=10)
ylim(0, 110)
yticks
ylabel('Temperature (C)', fontsize=10)

savefig(graphname)

GPIO.output(LED2_GPIO_PIN, GPIO.LOW)

User avatar
yv1hx
Posts: 379
Joined: Sat Jul 21, 2012 10:09 pm
Location: Now an expatriate, originally from Zulia, Venezuela
Contact: Website Skype

Re: Basic graphing module/idea help

Sun Jun 23, 2013 3:18 am

huggies15 wrote:Hi All,

I'm trying to get into programming (basic python programming) and have a problem.
I'm going to make a temperature sensor to record the time taken to boil some water etc.
Following the tutorial on the cambridge uni website (http://www.cl.cam.ac.uk/freshers/raspbe ... mperature/), I will end up (i think) with a file with a string of times and temperature.
What I want to do is have this data automatically converted to a simple graph and saved as an image, so i can print off both the raw data and a pretty graph.

What I dont know, is how to go about converting this data into a graph format, or what python modules are available and recommended to do this. I know I could load it into excel and do it manually, but I'm hoping to be creating 10s of these a day so dont want my time to be wasted doing that!

A basic idea of the setup (if it helps) is this: Headless RPi connected to the network, gathering data that i will store on a samba share on the Pi itself and hopefully then copy to a backup server daily. There is a printer on my main pc so the image(s) will be printed off manually at the end of each day.

Any help would be awesome, as i said, Im only starting to get to grips with how this works, and at the ripe old age of 26 my brain has already started to slow down on learning new things!

Cheers,
Steve
Hi Steve,

I'm monitoring my RPi SoC temperature using a bash script that gathers the temperature data every 2 minutes (using a crontab), then write on file using this notation:

HH:MM;Temp

Also, have other crontab task, running every minute, gathering the surrounding temperature (using a DS18B20 connected to the GPIO port), this data goes to another text file with similar notation, then another crontab every 5 minutes plots the data automagically and I can look the resulting graph in my local network, (using the RPi as web server, of course :D ).

Here is my gnuplot code, something rude, but works for me:

Code: Select all

set terminal png size 1200,500
# set terminal png size wide,height
set xdata time
set timefmt "%H:%M"
set format x "%H:%M"
# time range must be in same format as data file
set xrange ["00:00":"23:59"]
set datafile sep ';'
set output "/var/www/temp.png"
set yrange [27:67]
#set yrange autoscale
set grid
set xlabel "Time of day"
set ylabel "\nTemperature (c)"
set title "`date +%d-%b-%Y`\nSoC / Ambient temperature over time"
set key right box
set linetype 1 lw 1 lc rgb "blue"
set linetype 2 lw 1 lc rgb "red"
set linetype 3 lw 1 lc rgb "yellow"
plot "`date +%d-%b-%Y`.txt" using 1:2 index 0 title "SoC" with lines, "/home/pi/AmbientTemp/`date +%d-%b-%Y`.txt" using 1:2 title "Ambient" with lines, "limit.txt" using 1:2 title "58.6c safe limit" with lines
The file 'limit.txt' is a two line data file,

Code: Select all

00:00;58.6
23:59;58.6
only for pinpoint a warning line in the graph.

The resulting graph:
temp.png
temp.png (10.92 KiB) Viewed 4419 times
Please note that I'm using the semicolon symbol ; as field delimiter to avoid problems with commas , or periods . used as decimal separators.

Use the code as you wish, but no warranty is given!
Good luck :mrgreen:
Marco-Luis
Telecom Specialist (Now Available for Hire!)

http://www.meteoven.org
http://twitter.com/yv1hx

Return to “Python”