I'm creating a interactive chart with the seaborn package.
It's a simple chart with dates on the x axis and value from 0 to 5 on the y axis
I can move a cursor-bar over it left and right, with arrow keys and set the y value of the chart with num keys (and export to csv the charts y values with their timestamp).
However when large date ranges are used the program becomes incredibly slow.
I press the arrow keys to move the cursor one bar but it can take one or 2 seconds to react. (the key control are done with PyQT)
Any idea what i might do to speed it up?
Please feel free to copy paste the code and run it in python to see the program:
import matplotlib.pyplot as plt
import matplotlib
import pandas as pd
from datetime import timedelta, date
import numpy as np
matplotlib.use('Qt4Agg')
import seaborn as sns
from matplotlib.widgets import Button
import matplotlib.lines
from matplotlib.lines import Line2D
import csv
from itertools import izip
dates = []
values = []
sns.set(style="ticks")
fig = plt.figure(1, figsize=(25,7))
fig.clf()
ax = fig.add_subplot(111)
fig.canvas.draw()
plt.ylim(0,5)
horizontal_position = 0
periods = 365
idx = pd.DatetimeIndex(start='2010-01-01', freq='d', periods=periods)
index_delete = []
for i in range(idx.size):
if idx[i].dayofweek == 6 or idx[i].dayofweek == 5:
index_delete.append(i)
idx = idx.delete(index_delete)
periods = idx.size
idx_x_array = np.array(range(idx.size), dtype=np.int32)
str_vals = []
first_day_lines = []
counter = 0
if periods > 170:
for s in idx._data:
s = str(s)
day = s[8:10]
month = s[5:7]
year = s[0:4]
if day == '01':
dotted_line_f = plt.Line2D((counter, counter), (0, 5), lw=2., marker='.',
color='gray')
first_day_lines.append(dotted_line_f)
date_str = day+'/'+month+'/'+year
str_vals.append(date_str)
elif idx.dayofweek[counter]:
date_str = day+'/'+month
str_vals.append(date_str)
else:
str_vals.append('')
counter +=1
if periods <= 170:
for s in idx._data:
s = str(s)
day = s[8:10]
month = s[5:7]
year = s[0:4]
if day == '01':
dotted_line_f = plt.Line2D((counter, counter), (0, 5), lw=2., marker='.',
color='gray')
first_day_lines.append(dotted_line_f)
date_str = day+'/'+month+'/'+year
str_vals.append(date_str)
else:
date_str = day+'/'+month
str_vals.append(date_str)
counter +=1
plt.grid(True)
plt.xticks(idx_x_array, str_vals, rotation='vertical', fontsize=7)
values = []
for i in idx_x_array:
values.append(0)
data= pd.DataFrame({('A','a'):values}, idx)
sns.set_context(context={"figure.figsize":(5,5)})
ab = sns.tsplot(data.T.values, idx_x_array)
ab.lines[0].set_color('red')
# x_len = len(ab.lines[0]._x)
ab.lines[0]._x = idx_x_array
dotted_line = plt.Line2D((1, 1), (0, 5), lw=2.,
ls='-.', marker='.',
markersize=1,
color='black',
markerfacecolor='black',
markeredgecolor='black',
alpha=0.5)
ab.add_line(dotted_line)
for line in first_day_lines:
ab.add_line(line)
lines = ab.lines
init_focus = ab.lines[0]
index_focus = 0
bbox_props = dict(boxstyle="rarrow,pad=0.3", fc="pink", ec="b", lw=2)
horizontal_position = init_focus._x[index_focus]
plt.subplots_adjust(bottom=.30, left=.03, right=.97, top=.90, hspace=.35)
analysis_label = 'Analysis mode'
discovery_label = 'Discovery mode'
def chart_mode(event):
global button_label
global dotted_line
global power
global horizontal_position
global index_focus
global dotted_line
global idx
if button_label == analysis_label:
index_focus = 0
button_label = discovery_label
plt.draw()
elif button_label == discovery_label:
index_focus = periods-1
button_label = analysis_label
plt.draw()
bnext.label.set_text(button_label)
horizontal_position = ab.lines[0]._x[index_focus]
dotted_line = plt.Line2D((horizontal_position,horizontal_position), (0, 5), lw=5.,
ls='-.', marker='.',
markersize=1,
color='black',
markerfacecolor='black',
markeredgecolor='black',
alpha=0.5)
ax.add_line(dotted_line)
new_line = ax.lines.pop()
ax.lines[1] = new_line
def export_csv(event):
x_data = idx._data
y_data = ab.lines[0]._y
x_data_proc = []
for x in x_data:
x = str(x)
day = x[8:10]
month = x[5:7]
year = x[0:4]
date_str = day+'/'+month
x_data_proc.append(date_str)
y_data_proc = []
for y in y_data:
y_data_proc.append(int(y))
with open('some.csv', 'wb') as f:
writer = csv.writer(f)
writer.writerows(izip(x_data_proc, y_data_proc))
button_label = analysis_label
axnext = plt.axes([0.1, 0.05, 0.1, 0.075])
bnext = Button(axnext, button_label)
bnext.on_clicked(chart_mode)
axexport = plt.axes([0.21, 0.05, 0.1, 0.075])
bexport = Button(axexport, 'export csv')
bexport.on_clicked(export_csv)
def on_keyboard(event):
global power
global horizontal_position
global index_focus
global dotted_line
global idx
if event.key == 'right':
if index_focus < periods-1:
index_focus+=1
else:
idx = idx + timedelta(days=1)
index_focus+=1
elif event.key == 'left':
if index_focus > 0:
index_focus-=1
elif event.key == 'up':
if index_focus < periods-5:
index_focus+=5
elif event.key == 'down':
if index_focus > 5:
index_focus-=5
elif is_number(event.key):
for i in range(len(ab.lines[0]._y[index_focus::])):
ab.lines[0]._y[index_focus+i] = event.key
horizontal_position = ab.lines[0]._x[index_focus]
dotted_line = plt.Line2D((horizontal_position,horizontal_position), (0, 5), lw=2.,
ls='-.', marker='.',
markersize=1,
color='black',
markerfacecolor='black',
markeredgecolor='black',
alpha=0.5)
ax.add_line(dotted_line)
new_line = ax.lines.pop()
ax.lines[1] = new_line
fig.canvas.draw()
plt.show()
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
plt.gcf().canvas.mpl_connect('key_press_event', on_keyboard)
plt.show()
I'm afraid this code is too long for me to plough through.
Nonetheless, a couple of easy ways to help find bottlenecks:
interrupt the slow program, and look at the stack trace; repeat 5 times.
In your case these will have lots of incomprehensible calls in Qt4 etc.,
but you might be able to see what your code is calling that's slow.
good old print: add e.g. print "%.3f %s" % (time.time() - t0, event.key) in on_keyboard .
Then, comment out the drawing stuff, print only, run blind: is the time spent in drawing,
or somewhere else ?
Also, why Qt4Agg -- is TkAgg just as slow ?
Also, what does "when large date ranges are used" mean -- how large ?
Related
I got a .fig file generated in Matlab and I would like to display it in python environment, or at least retrieve the data. It works well when the original figure does not contain error bars. But when I have error bars then it looks like a staircase. Any ideas on how I could fix it?
The code I have been using is this:
## escape disti time for ions ##
size_f =26
def plotFig(filename,fignr=1):
from scipy.io import loadmat
from numpy import size
from matplotlib.pyplot import plot,figure,xlabel,ylabel,show,clf,xlim,ylim,legend,yticks,xticks
d = loadmat(filename,squeeze_me=True, struct_as_record=False)
ax1 = d['hgS_070000'].children
if size(ax1) > 1:
legs= ax1[1]
ax1 = ax1[0]
else:
legs=0
figure(fignr)
clf()
#hold(True)
counter = 0
counter1 =0
# x=np.zeros((1000,1000))
#y=np.zeros((1000,1000))
for line in ax1.children:
if line.type == 'graph2d.lineseries':
if hasattr(line.properties,'Marker'):
mark = "%s" % line.properties.Marker
mark = mark[0]
else:
mark = '.'
if hasattr(line.properties,'LineStyle'):
linestyle = "%s" % line.properties.LineStyle
else:
linestyle = '-'
if hasattr(line.properties,'Color'):
r,g,b = line.properties.Color
else:
r = 0
g = 0
b = 1
if hasattr(line.properties,'MarkerSize'):
marker_size = line.properties.MarkerSize
else:
marker_size = 1
#if counter1 ==0:
x = line.properties.XData
y = line.properties.YData
#counter1=1
#else:
# x1 = line.properties.XData
# y1 = line.properties.YData
if counter ==0:
x = line.properties.XData
y = line.properties.YData
plt.plot(x[y>0],y[y>0],linestyle=linestyle,linewidth=3.0)
counter=1
elif counter==1:
x1 = line.properties.XData
y1 = line.properties.YData
#plt.plot(x1[y1>0],y1[y1>0],linestyle=linestyle,linewidth=3.0)
counter=2
else:
x = line.properties.XData
y = line.properties.YData
plt.plot(x[y>0],y[y>0],linestyle=linestyle,linewidth=4.0,color=[r,g,b])
plt.yscale('log')
plt.xscale('log')
elif line.type == 'text':
if counter < 1:
xlabel(r'$%s$' % line.properties.String,fontsize =18)
#xlabel('%s' % line.properties.String,fontsize = 18)
counter += 1
elif counter < 2:
ylabel(r'$%s$' % line.properties.String,fontsize = 18)
# ylabel('%s' % line.properties.String,fontsize = 18)
counter += 1
ylim(1e-7,1e-1)
#ylim(ax1.properties.YLim)
xlim((1e-2, 1e3))
plt.rcParams["figure.figsize"] = [10,8]
plt.tick_params(axis='x',labelsize=size_f)
plt.tick_params(axis='y',labelsize=size_f)
plt.ylabel(r'$p(t_{esc})$', fontsize=size_f)
plt.xlabel(r'$t_{esc} \ [sec]$', fontsize=size_f)
#plt.savefig(r'C:\Users\nikos.000\vlahos\png\escape distr_elec.png', format='png',dpi=300)#,bbox_inches='tight')
#plt.savefig(r'C:\Users\nikos.000\vlahos\eps\escape_distr_elec.eps', format='eps',dpi=300)#,bbox_inches='tight')
#### Set tick size ####
labels = [r'$10^{-2}$', r'$10^{-1}$',r'$10^{0}$',r'$10^{1}$',r'$10^{2}$', r'$10^{3}$']#,r'$10^{2}$',r'$10^{4}$']
x = [1e-2,1e-1,1e0,1e1,1e2,1e3]
plt.tick_params(axis='x',labelsize=size_f)
plt.tick_params(axis='y',labelsize=size_f)
plt.xticks(x, labels)
labels1 = [r'$10^{-6}$', r'$10^{-4}$', r'$10^{-2}$']
y = [1e-6,1e-4, 1e-2,]
plt.yticks(y, labels1)
if legs:
leg_entries = tuple(legs.properties.String)
py_locs = ['upper center','lower center','right','left','upper right','upper left','lower right','lower left','best']
MAT_locs=['north','south','east','west','northeast', 'northwest', 'southeast', 'southwest','best']
Mat2py = dict(zip(MAT_locs,py_locs))
location = legs.properties.Location
leg1=legend(leg_entries,loc=Mat2py[location],frameon=False,fontsize=size_f)
leg1.legendHandles[1].set_color('black')
#plt.xticks(fontsize=18 )
#plt.yticks(fontsize=18)
#### Save figure ####
plt.savefig(r'C:\Users\nikos.000\vlahos\png\escape distr_prot.png', format='png',dpi=300,bbox_inches='tight')
plt.savefig(r'C:\Users\nikos.000\vlahos\eps\escape_distr_prot.eps', format='eps',dpi=300,bbox_inches='tight')
show()
return
plotFig(r'C:\Users\nikos.000\neutrons\f5b P=1.fig',fignr=1)
This is how the figure looks:
The original .fig file can be found here:
https://www.dropbox.com/sh/iddxpfvxz85abci/AAAU9p0DM5OYtpI7mE-nLAuga?dl=0
I am currently working on a Yee Solver script for uni, but when I try to animate my 3D graph, the graph is not what is expected. It works for a 2D plot, but I can't seem to translate that into 3D. From my understanding, set_data and set_3d_properties need a 1D array to work, which I am inputting.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib.widgets import Slider
# Program Variables
wv_lgth_num = 10
graph_type = '3d'
t = 0
# Physical Constants
c = 3e8
mu_r = 1
eps_r = 1
# Source Constants
f = 2e9
omega = 2*f*(np.pi)
amp = 1.0
wv_lgth = c/f
period = 1/f
# Step size
dz = wv_lgth/20
dt = ((c/f)/20)/c
#dt = ((1/f)/20)/1
# Axis Grids
z_grid = np.arange(0,wv_lgth_num*wv_lgth,dz)
t_grid = np.arange(0,10*period,dt)
# Number of steps
num_z = z_grid.size
num_t = t_grid.size
# Coefficients
coe_E = c*dt/(eps_r*dz)
coe_H = c*dt/(mu_r*dz)
# E and H Matricies
E_mat = np.zeros((num_z,num_t))
H_mat = np.zeros((num_z,num_t))
# Generating Values for E and H
for time in range(0,num_t-1):
for pos in range(0,num_z-1):
# Source Wave
if pos == 0:
H_mat[0,time] = amp*np.sin(omega*t_grid[time])
# All cases of Yee Solver
if pos == 1:
if time == 0:
H_mat[1,0] = 0
E_mat[0,0] = 0
else:
H_mat[1,time] = H_mat[1,time-1] + coe_H*(E_mat[1,time-1] - E_mat[0,time-1])
E_mat[0,time] = E_mat[0,time-1] + coe_E*(H_mat[1,time] - H_mat[0,time])
if pos > 1 and pos != num_z-1:
if time == 0:
H_mat[pos,0] = 0
E_mat[pos-1,0] = 0
if time > 0:
H_mat[pos,time] = H_mat[pos,time-1] + coe_H*(E_mat[pos,time-1] - E_mat[pos-1,time-1])
E_mat[pos-1,time] = E_mat[pos-1,time-1] + coe_E*(H_mat[pos,time] - H_mat[pos-1,time])
if pos == num_z-1:
if time == 0:
H_mat[num_z-1,0] = 0
E_mat[num_z-2,0] = 0
E_mat[num_z-1,0] = 0
if time > 0:
H_mat[num_z-1,time] = H_mat[num_z-1,time-1] + coe_H*(E_mat[num_z-1,time-1] - E_mat[num_z-2,time-1])
E_mat[num_z-2,time] = E_mat[num_z-2,time-1] + coe_E*(H_mat[num_z-1,time] - H_mat[num_z-2,time])
E_mat[num_z-1,time] = E_mat[num_z-2,time]
def update(val):
t = slider_time.val
if graph_type == '2d':
a.set_ydata(E_mat[:,t])
b.set_ydata(H_mat[:,t])
if graph_type == '3d':
a.set_3d_properties(E_mat[:,t])
a.set_data(z_grid,np.zeros((num_z,num_t))[:,t])
b.set_3d_properties(np.zeros((num_z,num_t))[:,t])
b.set_data(z_grid,H_mat[:t])
fig.canvas.draw_idle()
print(H_mat)
print(H_mat[:,t].size)
print(z_grid)
print(np.zeros((num_z,num_t))[:,t].size)
# Creating plot
if graph_type == '3d':
fig, ax = plt.subplots()
ax = plt.axes(projection='3d')
b, = ax.plot3D(z_grid,H_mat[:,t],np.zeros((num_z,num_t))[:,t], label='H')
a, = ax.plot3D(z_grid,np.zeros((num_z,num_t))[:,t],E_mat[:,t], label='E')
plt.title('Light Wave')
ax.set_xlabel('z')
ax.set_ylabel('x')
ax.set_zlabel('y')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
if graph_type == '2d':
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
a, = plt.plot(z_grid,E_mat[:,t], label='E (yz plane)')
b, = plt.plot(z_grid,H_mat[:,t], label='H (xz plane)')
plt.title('Light Wave')
plt.xlabel('z')
plt.ylabel('x')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
Any help would be appreciated. The middle for loop is just generating my functions, using the Yee Method.
When I run my code I create a figure, then I create a subplot in that figure. Then when I try to add a title to it using ax.set_title("title") it sometimes shows up for a split second then goes away. I have tried using plot.title aswell with no luck.
I tried recreating the error in a small example but for some reason it worked just fine there, so here is the entire source code of the code.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.style as style
import plotgen
from matplotlib.widgets import Button
class plotWindow():
def __init__(self):
style.use("bmh")
self.dp = 30
self.fig = plt.figure()
self.ax = self.fig.add_subplot(1, 1, 1, label="ax1")
self.cax = 1
self.maxax = 2
self.minax = 1
plotgen.clear("plot1.txt")
plotgen.clear("plot2.txt")
axnext = plt.axes([0.80, 0.01, 0.06, 0.06])
axprev = plt.axes([0.73, 0.01, 0.06, 0.06])
bnext = Button(axnext, 'Next >')
bnext.on_clicked(self.changePlotNext)
bprev = Button(axprev, "< Previous")
bprev.on_clicked(self.changePlotPrev)
ani = animation.FuncAnimation(self.fig, self.animate, interval=500)
plt.show()
def changePlotNext(self, i):
if self.cax < self.maxax:
self.cax += 1
self.ax.set_title("Pump " + str(self.cax))
def changePlotPrev(self, i):
if self.cax > self.minax:
self.cax -= 1
self.ax.set_title("Pump " + str(self.cax))
def animate(self, i):
if self.cax == 1:
plotgen.generate("plot1.txt")
graph_data = open('plot1.txt', 'r').read()
lines = graph_data.split('\n')
xs = []
ys = []
for line in lines:
if len(line) > 1:
x, y = line.split(',')
xs.append(x)
ys.append(float(y))
self.ax.clear()
lx = len(xs)
ly = len(ys)
if len(xs) < self.dp:
pxs = xs
pys = ys
else:
pxs = xs[(lx - (self.dp - 1)):(lx - 1)]
pys = ys[(ly - (self.dp - 1)):(ly - 1)]
self.ax.plot(pxs, pys, "r")
elif self.cax == 2:
plotgen.generate("plot2.txt")
graph_data = open('plot2.txt', 'r').read()
lines = graph_data.split('\n')
xs = []
ys = []
for line in lines:
if len(line) > 1:
x, y = line.split(',')
xs.append(x)
ys.append(float(y))
self.ax.clear()
lx = len(xs)
ly = len(ys)
if len(xs) <= self.dp:
pxs = xs
pys = ys
else:
pxs = xs[(lx - (self.dp - 1)):(lx - 1)]
pys = ys[(ly - (self.dp - 1)):(ly - 1)]
self.ax.plot(pxs, pys)
plotWindow()
As you can see in my changePlotNext and changePlotPrev functions I'm trying to change the title. Sometimes they display for a split second when I change, but then it goes away. And I am very aware that I have not set a title to display before I change the plot.
In animate, you have self.ax.clear(), which is removing all artists, texts, etc. on the Axes, including the title.
A simple option, then, is to reset the title after you clear the axes. So if you add:
self.ax.set_title("Pump " + str(self.cax))
in both places, immediately after you call self.ax.clear(), your titles will still be shown.
Another option would be to stop clearing the axes, but just remove the items you need to remove. I think this is just the lines you have plotted? So, for example, you could remove the call to self.ax.clear(), and add:
for line in self.ax.lines:
line.remove()
in its place. That will remove just the plotted line, but retain the title.
i am new to python. I am writing a data logging program and want to open a serial port, then read from it.
My problem is that calling this in my main():
# Handle serial
ser = serial.Serial(strPort, 9600)
doesnt allow me to invoke methods on the ser handle in other functions. Should i make a class or whats the best approach?
Here is the error message:
line 164, in updateData
line = ser.readline().rstrip()
NameError: name 'ser' is not defined
Here is the code:
# Uncomment the next two lines if you want to save the animation
import matplotlib
# matplotlib.use("Agg")
import sys
import serial
import argparse
import csv
import numpy
from matplotlib.pylab import *
from mpl_toolkits.axes_grid1 import host_subplot
import matplotlib.animation as animation
'''
ax03.legend([p031,p032], [p031.get_label(),p032.get_label()])
'''
def main():
# Sent for figure
font = {'size': 9}
matplotlib.rc('font', **font)
# Setup figure and subplots
f0 = figure(num=0, figsize=(12, 10)) # , dpi = 100)
f0.suptitle("Sensor Data", fontsize=12)
ax01 = subplot2grid((3, 2), (1, 0))
#ax02 = subplot2grid((4, 2), (1, 1))
ax02 = ax01.twinx()
ax03 = subplot2grid((3, 2), (0, 0), colspan=2, rowspan=1)
ax04 = subplot2grid((3, 2), (1, 1))
ax05 = subplot2grid((3, 2), (2, 0))
ax06 = subplot2grid((3, 2), (2, 1))
subplots_adjust(left=None, bottom=None, right=None,
top=None, wspace=0.3, hspace=0.3)
# Set titles of subplots
ax01.set_title('Heart Rate Quality and Sample Frequency')
ax03.set_title('Heart Rate')
ax04.set_title('Step Rate')
ax05.set_title('Perfusion Index')
ax06.set_title('Raw PPG')
# set y-limits
ax01.set_ylim(-1, 5)
ax02.set_ylim(100, 500)
ax03.set_ylim(30, 140)
ax04.set_ylim(-50, 250)
ax05.set_ylim(0, 500)
ax06.set_ylim(0, 50000)
# sex x-limits
ax01.set_xlim(0, 50.0)
# ax02.set_xlim(0,50.0)
ax03.set_xlim(0, 50.0)
ax04.set_xlim(0, 50.0)
ax05.set_xlim(0, 50.0)
ax06.set_xlim(0, 50.0)
# Turn on grids
ax01.grid(True)
# ax02.grid(True)
ax03.grid(True)
ax04.grid(True)
ax05.grid(True)
ax06.grid(True)
# set label names
ax01.set_xlabel("t[s]")
ax01.set_ylabel("HRQ")
ax02.set_xlabel("t[s]")
ax02.set_ylabel("samples[Hz]")
ax03.set_xlabel("t[s]")
ax03.set_ylabel("bpm")
ax04.set_xlabel("t[s]")
ax04.set_ylabel("Steps/min")
ax05.set_xlabel("t[s]")
ax05.set_ylabel("AC/DC ratio")
ax06.set_xlabel("t[s]")
ax06.set_ylabel("raw PS sample")
# Data Placeholders
t = zeros(0)
hr = zeros(0)
HRQ = zeros(0)
Fs = zeros(0)
stepRate = zeros(0)
ADCGain = zeros(0)
pI = zeros(0)
rawPPG = zeros(0)
ser = zeros(0)
# set plots
p011, = ax01.plot(t, HRQ, 'c-', label="HRQ", linewidth=2)
p021, = ax02.plot(t, ADCGain, 'r-', label="Sample Frequency", linewidth=2)
p031, = ax03.plot(t, hr, 'b-', label="Heart Rate", linewidth=2)
p041, = ax04.plot(t, stepRate, 'b-', label="Step Rate", linewidth=2)
p051, = ax05.plot(t, pI, 'y-', label="Perfusion Index", linewidth=2)
p061, = ax06.plot(t, rawPPG, 'g-', label="Raw PPG", linewidth=2)
# set lagends
ax01.legend([p011, p021], [p011.get_label(), p021.get_label()], loc=2)
#ax02.legend([p021], [p021.get_label()])
ax03.legend([p031], [p031.get_label()], loc=2)
ax04.legend([p041], [p041.get_label()], loc=2)
ax05.legend([p051], [p051.get_label()], loc=2)
ax06.legend([p061], [p061.get_label()], loc=2)
# Data Update
xmin = 0.0
xmax = 50.0
x = 0.0
# create parser
parser = argparse.ArgumentParser(description="LDR serial")
# add expected arguments
parser.add_argument('--port', dest='port', required=True)
# parse args
args = parser.parse_args()
#strPort = '/dev/tty.usbserial-A7006Yqh'
strPort = args.port
print('reading from serial port %s...' % strPort)
# Handle serial
ser = serial.Serial(strPort, 9600)
print('plotting data...')
# Logfile writer
# open('test.csv','w') as csvfile
#logwriter = csv.writer(csvfile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
# interval: draw new frame every 'interval' ms
# frames: number of frames to draw
simulation = animation.FuncAnimation(
f0, updateData, blit=False, frames=1000, interval=100, repeat=True)
# Uncomment the next line if you want to save the animation
# simulation.save(filename='sim.mp4',fps=1,dpi=300)
plt.show()
def updateData(self):
global x
global t
global ser
global hr
global HRQ
global Fs
global ADCGain
global stepRate
global pI
global rawPPG
try:
line = ser.readline().rstrip()
data = [float(val) for val in line.split()]
# print data
print(data)
if(len(data) == 9):
# log data
for i in range(len(data)):
out_string = ""
out_string += str(data[i])
# logwriter.writerow(out_string)
# update variables
tmpT = data[0]
tmpFs = data[1]
tmpStepRate = data[2]
tmpHr = data[3]
tmpPI = data[4]
tmpHRQ = data[5]
tmpRawPPG = data[6]
except KeyboardInterrupt:
print('exiting')
hr = append(hr, tmpHr)
HRQ = append(HRQ, tmpHRQ)
Fs = append(Fs, tmpFs)
stepRate = append(stepRate, tmpStepRate)
pI = append(pI, tmpPI)
rawPPG = append(rawPPG, tmpRawPPG)
t = append(t, x)
x += 1
p011.set_data(t, HRQ)
p021.set_data(t, Fs)
p031.set_data(t, hr)
p041.set_data(t, stepRate)
p051.set_data(t, pI)
p061.set_data(t, rawPPG)
if x >= xmax - 10.00:
p011.axes.set_xlim(x - xmax + 10.0, x + 10.0)
p021.axes.set_xlim(x - xmax + 10.0, x + 10.0)
p031.axes.set_xlim(x - xmax + 10.0, x + 10.0)
p041.axes.set_xlim(x - xmax + 10.0, x + 10.0)
p051.axes.set_xlim(x - xmax + 10.0, x + 10.0)
p061.axes.set_xlim(x - xmax + 10.0, x + 10.0)
return p011, p021, p031, p041, p051, p061
# Call main
if __name__ == '__main__':
main()
I am getting a very strange error using basemap. No error appears, yet my 3rd plot has no data plotted when data does indeed exist. Below is my code. When run, you will see that both modis and seawifs data is plotted, but viirs is not. I can't figure out why.
import numpy as np
import urllib
import urllib2
import netCDF4
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from datetime import datetime, date, time, timedelta
import json
import math
def indexsearch(datebroken,year, month, day):
for i in range(0,len(datebroken)):
if (datebroken[i,0] == year and datebroken[i,1] == month and datebroken[i,2] == day):
return i
url = 'http://coastwatch.pfeg.noaa.gov/erddap/griddap/erdMWchlamday.nc?chlorophyll' +\
'[(2002-07-16T12:00:00Z):1:(2015-04-16T00:00:00Z)][(0.0):1:(0.0)][(36):1:(39)][(235):1:(240)]'
file = 'erdMWchlamday.nc'
urllib.urlretrieve(url, file)
ncfilemod = netCDF4.Dataset(file)
ncv1 = ncfilemod.variables
print ncv1.keys()
time1=ncv1['time'][:]
inceptiondate = datetime(1970, 1, 1, 0, 0, 0)
timenew1=[]
for i in time1[:]:
newdate = inceptiondate + timedelta(seconds=i)
timenew1.append(newdate.strftime('%Y%m%d%H'))
datebroken1 = np.zeros((len(timenew1),4),dtype=int)
for i in range(0,len(timenew1)):
datebroken1[i,0] = int(timenew1[i][0:4])
datebroken1[i,1] = int(timenew1[i][4:6])
datebroken1[i,2] = int(timenew1[i][6:8])
datebroken1[i,3] = int(timenew1[i][8:10])
lon1= ncv1['longitude'][:]
lat1 = ncv1['latitude'][:]
lons1, lats1 = np.meshgrid(lon1,lat1)
chla1 = ncv1['chlorophyll'][:,0,:,:]
url = 'http://coastwatch.pfeg.noaa.gov/erddap/griddap/erdSWchlamday.nc?chlorophyll' +\
'[(1997-09-16):1:(2010-12-16T12:00:00Z)][(0.0):1:(0.0)][(36):1:(39)][(235):1:(240)]'
file = 'erdSWchlamday.nc'
urllib.urlretrieve(url, file)
#Ncfile 2
ncfilewif = netCDF4.Dataset(file)
ncv2 = ncfilewif.variables
print ncv2.keys()
time2=ncv2['time'][:]
inceptiondate = datetime(1970, 1, 1, 0, 0, 0)
timenew2=[]
for i in time2[:]:
newdate = inceptiondate + timedelta(seconds=i)
timenew2.append(newdate.strftime('%Y%m%d%H'))
datebroken2 = np.zeros((len(timenew2),4),dtype=int)
for i in range(0,len(timenew2)):
datebroken2[i,0] = int(timenew2[i][0:4])
datebroken2[i,1] = int(timenew2[i][4:6])
datebroken2[i,2] = int(timenew2[i][6:8])
datebroken2[i,3] = int(timenew2[i][8:10])
lon2= ncv2['longitude'][:]
lat2 = ncv2['latitude'][:]
lons2, lats2 = np.meshgrid(lon2,lat2)
chla2 = ncv2['chlorophyll'][:,0,:,:]
url = 'http://coastwatch.pfeg.noaa.gov/erddap/griddap/erdVH2chlamday.nc?chla' +\
'[(2012-01-15):1:(2015-05-15T00:00:00Z)][(39):1:(36)][(-125):1:(-120)]'
file = 'erdVH2chlamday.nc'
urllib.urlretrieve(url, file)
ncfileviir = netCDF4.Dataset(file)
ncv3 = ncfileviir.variables
print ncv3.keys()
time3=ncv3['time'][:]
inceptiondate = datetime(1970, 1, 1, 0, 0, 0)
timenew3=[]
for i in time3[:]:
newdate = inceptiondate + timedelta(seconds=i)
timenew3.append(newdate.strftime('%Y%m%d%H'))
datebroken3 = np.zeros((len(timenew3),4),dtype=int)
for i in range(0,len(timenew3)):
datebroken3[i,0] = int(timenew3[i][0:4])
datebroken3[i,1] = int(timenew3[i][4:6])
datebroken3[i,2] = int(timenew3[i][6:8])
datebroken3[i,3] = int(timenew3[i][8:10])
lon3= ncv3['longitude'][:]
lat3 = ncv3['latitude'][:]
lons3, lats3 = np.meshgrid(lon3,lat3)
chla3 = ncv3['chla'][:,:,:]
i1=indexsearch(datebroken1,2012,6,16)
print i1
i2=indexsearch(datebroken2,2010,6,16)
print i2
i3=indexsearch(datebroken3,2012,6,15)
print i3
chla1plot = chla1[i1,:,:]
chla2plot = chla2[i2,:,:]
chla3plot = chla3[i3,:,:]
ncfileviir.close()
ncfilemod.close()
ncfilewif.close()
Important code is below here. All code above is just pulling the data into python to plot.
minlat = 36
maxlat = 39
minlon = 235
maxlon = 240
# Create map
fig = plt.figure()
#####################################################################################################################
#plot figure 1
ax1 = fig.add_subplot(221)
m = Basemap(projection='merc', llcrnrlat=minlat,urcrnrlat=maxlat,llcrnrlon=minlon, urcrnrlon=maxlon,resolution='h')
cs1 = m.pcolormesh(lons1,lats1,chla1plot,cmap=plt.cm.jet,latlon=True)
m.drawcoastlines()
m.drawmapboundary()
m.fillcontinents()
m.drawcountries()
m.drawstates()
m.drawrivers()
#Sets up parallels and meridians.
parallels = np.arange(36.,39,1.)
# labels = [left,right,top,bottom]
m.drawparallels(parallels,labels=[False,True,True,False])
meridians = np.arange(235.,240.,1.)
m.drawmeridians(meridians,labels=[True,False,False,True])
ax1.set_title('Modis')
#####################################################################################################################
#plot figure 2
ax2 = fig.add_subplot(222)
cs2 = m.pcolormesh(lons2,lats2,chla2plot,cmap=plt.cm.jet,latlon=True)
m.drawcoastlines()
m.drawmapboundary()
m.fillcontinents()
m.drawcountries()
m.drawstates()
m.drawrivers()
#Sets up parallels and meridians.
parallels = np.arange(36.,39,1.)
# labels = [left,right,top,bottom]
m.drawparallels(parallels,labels=[False,True,True,False])
meridians = np.arange(235.,240.,1.)
m.drawmeridians(meridians,labels=[True,False,False,True])
ax2.set_title('SeaWIFS')
#####################################################################################################################
#plot figure 3
ax3 = fig.add_subplot(223)
cs3 = m.pcolormesh(lons3,np.flipud(lats3),np.flipud(chla3plot),cmap=plt.cm.jet,latlon=True)
m.drawcoastlines()
m.drawmapboundary()
m.fillcontinents()
m.drawcountries()
m.drawstates()
m.drawrivers()
#Sets up parallels and meridians.
parallels = np.arange(36.,39,1.)
# labels = [left,right,top,bottom]
m.drawparallels(parallels,labels=[False,True,True,False])
meridians = np.arange(235.,240.,1.)
m.drawmeridians(meridians,labels=[True,False,False,True])
ax3.set_title('VIIRS')
# Save figure (without 'white' borders)
#plt.savefig('SSTtest.png', bbox_inches='tight')
plt.show()
My results are shown here!
![results]: http://i.stack.imgur.com/dRjkU.png
The issue that I found was that I had
minlat = 36
maxlat = 39
minlon = 235
maxlon = 240
m = Basemap(projection='merc', llcrnrlat=minlat,urcrnrlat=maxlat,llcrnrlon=minlon, urcrnrlon=maxlon,resolution='h')
The final plot was -125 to -120 which basemap did not automatically handle, but instead placed the plot at an area where I did not have data. I added a new m = basemap statement and changed the meridian numbers for the third graph using -125 to -120 as my longitude and the graph plotted just fine.