Reputation: 2723
I'm playing around with my raspberry pi sensors and trying to make a decent plot of the readings. Now I am savind all the data into a google docs: https://docs.google.com/spreadsheet/ccc?key=0AqwhQwJogqG0dDBiU1RuNzlKM1V5OXB3dkRPamctbnc#gid=0 And using both data+time and a unix timestamp to save the time.
Plotting with the unix time works perfectly
But I would like to use real time as the axis (or as a subaxis) But I can't seem to read it in nor plot it.
import numpy as np
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt
#import data
data = np.loadtxt('DHT11.csv', delimiter = ',', skiprows = 1,
usecols = (0,2,3,4,5,6), unpack = 1)
#id, unixtime, temp, humidity, lightlevel, lightvolt
i = data[0]
time = data[1]
temp = data[2]
hum = data[3]
light_lv = 1/data[4]*1000
light_v = data[5]
if 1:
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)
par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",
axes=par2,
offset=(offset, 0))
par2.axis["right"].toggle(all=True)
#host.set_xlim(0, 2)
#host.set_ylim(0, 2)
host.set_xlabel("Time (unix)")
host.set_ylabel("Temperature (C)")
par1.set_ylabel("Humidity (%)")
par2.set_ylabel("Light (A.U.)")
p1, = host.plot(time, temp)
p2, = par1.plot(time, hum)
p3, = par2.plot(time, light_lv)
#par1.set_ylim(0, 4)
#par2.set_ylim(1, 65)
host.legend()
host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
par2.axis["right"].label.set_color(p3.get_color())
plt.draw()
plt.show()
#plt.savefig("Test")
Could anyone please help out?
Upvotes: 2
Views: 3129
Reputation: 879361
You could define a custom formatter (see below), but if you do it that way you'd need to define the formatter for each axis, host
, par1
, par2
.
I think an easier solution would be to convert your time
to Python datetime.datetime
objects, and let Matplotlib handle the formatting. You could still use a custom formatter if you don't like how Matplotlib formats the dates.
import datetime as DT
time = [DT.datetime.fromtimestamp(t/1000) for t in time]
...
p1, = host.plot(time, temp)
p2, = par1.plot(time, hum)
p3, = par2.plot(time, light_lv)
By the way, you can define i
, time
, temp
, etc. directly (without using the temp variable data
):
i, time, temp, hum, light_lv, light_v = np.loadtxt(
'DHT11.csv', delimiter = ',', skiprows = 1,
usecols = (0,2,3,4,5,6), unpack = 1)
time = [DT.datetime.fromtimestamp(t/1000) for t in time]
light_lv = 1.0/light_lv*1000
If the x-axis
values are Python datetime.datetime
objects, to set a custom formatter, use
import matplotlib.dates as mdates
xfmt = mdates.DateFormatter('%Y-%m-%d %H:%M:%S')
ax.xaxis.set_major_formatter(xfmt)
If the x-axis
values are timestamps, use
import datetime as DT
import matplotlib.ticker as ticker
xfmt = ticker.FuncFormatter(lambda timestamp, pos: DT.fromtimestamp(x/1000.0).strftime('%Y-%m-%d'))
ax.xaxis.set_major_formatter(xfmt)
Where ax
is host
, par1
, and/or par2
.
Upvotes: 1
Reputation: 77951
If you convert your data to pandas
time series, it will automatically do that for you. it will also choose appropriate label format according to frequency of the data. For example if your data come in seconds:
import pandas as pd
import numpy as np
n = 100
idx = pd.date_range( start=dt.datetime.now( ), periods=n, freq='S' )
ts1= pd.Series( np.sin( np.linspace( 0, 4 * np.pi, n ) ), index=idx)
ts2= pd.Series( np.cos( np.linspace( 0, 4 * np.pi, n ) ), index=idx)
fig = plt.figure( figsize=(8, 6) )
ax = fig.add_axes( [.05, .05, .9, .9] )
ts1.plot( ax )
ts2.plot( ax )
(ts1 - ts2).plot( ax )
you get this:
and if you have daily data:
ts= pd.Series( np.sin( np.linspace( 0, 4 * np.pi, n ) ),
index=pd.date_range( start=dt.datetime.now( ), periods=n, freq='D' ))
ts.plot( )
Upvotes: 0