I create code to read a csv file.
the error message is
File "C:/Users/amori/Desktop/programas de python/Nova
pasta/alg1.py", line 17, in get_data
csvFileReader = csv.reader(csvfile)
NameError: name 'csvfile' is not defined
Can someone help me with this code? what I am doing wrong?
import csv
import numpy as np
from sklearn.svm import SVR
import matplotlib.pyplot as plt
dates = []
prices = []
def get_data(filename):
with open(filename, 'r') as csvfile_:
csvFileReader = csv.reader(csvfile)
next(csvFileReader)
for row in csvFileReader:
dates.append(int(row[0].split('-')[0]))
prices.append(float(row[1]))
return
def predict_prices(dates, proces, x):
dates = np.reshape(dates,(len(dates),1))
svr_len = SVR(kernal = 'liner', c = 1e3)
svr_poly = SVR(kernal = 'poly', c = 1e3, degree = 2)
svr_rbf = SVR(kernal = 'rbf', c = 1e3, gamma = 0.1)
svr_lin.fit(dates, prices)
svr_ply.fit(dates, prices)
svr_rbf.fit(dates, prices)
plt.scatter(dates, prices, color='black', label='data')
plt.plot(dates, svr_rbf.predict(dates), color='red', label='RBF model')
plt.plot(dates, svr_lin.predict(dates), color='green', label='linear model')
plt.plot(dates, svr_poly.predict(dates), color='blue', label='Polynomial model')
plt.xlavell('date')
plt.title('price')
plt.title('support vector regression')
plt.legend()
plt.show()
return svr_rbf.predict(x)[0], svr_lin.predict(x)[0], svr_poly.predict(x)[0]
get_data('aapl.csv')
predicted_price = predict_pice[dates, prices, 29]
print(predicted_price)
you have an underscore that's not wanted:
with open(filename, 'r') as csvfile_:
should be
with open(filename, 'r') as csvfile:
Related
I try to create a live graph with matplotlib animation. below code report error:
UnboundLocalError: local variable 'lines' referenced before assignment
lines is defined above!
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
queue = []
qSize = 20
N = 3
lines = []
xidx = list(range(0, qSize))
def init():
for i in range(qSize):
queue.append([0]*N)
for i in range(N):
xdata = []
ydata = []
line, = ax.plot(xdata, ydata,label=str(i))
lines.append([line,xdata,ydata])
ax.legend(loc=2)
plt.xticks(rotation=45, ha='right')
#plt.subplots_adjust(bottom=0.30)
plt.title('Demo')
plt.ylabel('x')
plt.ylabel('Value')
return
def tick():
arr = []
for i in range(N):
d = random.randint(i*10,i*10+5)
arr.append(d)
queue.append(arr)
lines = lines[-qSize:]
return
def animate(i):
tick()
df = pd.DataFrame(data)
ax.set_xlim(0,qSize)
ax.set_ylim(df.min().min(),df.max().max())
for i,colname in enumerate(df.columns):
line,xdata,ydata = lines[i]
xdata = xidx
ydata = df[colname]
line.set_xdata(xdata)
line.set_ydata(ydata)
plt.draw()
return
init()
ani = animation.FuncAnimation(fig, animate, fargs=(), interval=1000)
plt.show()
I'm new to Python and I'm trying to combine two scripts together. The first script reads a value from a sensor and writes it to a .csv file.
#!/usr/bin/python
import csv
import spidev
import time
#Define Variables
x_value = 0
pad_value = 0
delay = 0.1
pad_channel = 0
fieldnames = ["x_value", "pad_value"]
#Create SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000
def readadc(adcnum):
# read SPI data from the MCP3008, 8 channels in total
if adcnum > 7 or adcnum < 0:
return -1
r = spi.xfer2([1, 8 + adcnum << 4, 0])
data = ((r[1] & 3) << 8) + r[2]
return data
#Write headers
with open('data.csv', 'w') as csv_file:
csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
csv_writer.writeheader()
#Write values
while True:
with open('data.csv', 'a') as csv_file:
csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
info = {
"x_value": x_value,
"pad_value": pad_value
}
csv_writer.writerow(info)
#Update values
x_value += 1
pad_value = readadc(pad_channel)
print(x_value, pad_value)
time.sleep(delay)
The second script reads the .csv file and plots the data to a graph using matplotlib.
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
plt.style.use('fivethirtyeight')
def animate(i):
data = pd.read_csv('data.csv')
x = data['x_value'].tail(600)
y = data['pad_value'].tail(600)
plt.cla()
plt.plot(x, y)
ani = FuncAnimation(plt.gcf(), animate, interval=100)
plt.tight_layout()
plt.show()
I can run both scripts separately and they work, but I want to combine them into a single script.
I've tried to merge them, but when it gets to plt.show() it shows the graph but doesn't continue. I tried plt.show(block=False), which continues, but doesn't show the graph.
#!/usr/bin/python
import csv
import spidev
import time
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
#Define Variables
x_value = 0
pad_value = 0
delay = 0.1
pad_channel = 0
fieldnames = ["x_value", "pad_value"]
#Create SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000
def readadc(adcnum):
# read SPI data from the MCP3008, 8 channels in total
if adcnum > 7 or adcnum < 0:
return -1
r = spi.xfer2([1, 8 + adcnum << 4, 0])
data = ((r[1] & 3) << 8) + r[2]
return data
#Animate graph
def animate(i):
data = pd.read_csv('data.csv')
x = data['x_value']
y = data['pad_value']
plt.cla()
plt.plot(x, y)
plt.style.use('fivethirtyeight')
plt.tight_layout()
plt.show(block=False)
#Write headers to CSV file
with open('data.csv', 'w') as csv_file:
csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
csv_writer.writeheader()
#Append values to CSV file
while True:
with open('data.csv', 'a') as csv_file:
csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
info = {
"x_value": x_value,
"pad_value": pad_value
}
csv_writer.writerow(info)
#Update values
x_value += 1
pad_value = readadc(pad_channel)
print(x_value, pad_value)
time.sleep(delay)
plt.style.use('fivethirtyeight')
ani = FuncAnimation(plt.gcf(), animate, interval=100)
plt.tight_layout()
plt.show(block=False)
Is there a simple way to combine these two?
You can interactively change data on the canvas by setting the plot to interactive mode like this:
import matplotlib.pyplot as plt
import numpy as np
import time
phase = 0
delay = 0.1
t = 0
x = np.linspace(t, t+2, 200)
data = 0.5*np.sin(x)+.5
#Setting interactive mode on plt
plt.ion()
#create new figure
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim((-1.1, 1.1))
line1, = ax.plot(x, data, 'b-')
while True:
#I generate some random data, you will use your data (from the csv)
x = np.linspace(t, t+2, 200)
data = np.sin(x)
line1.set_ydata(data)
line1.set_xdata(x)
#Set the xlim to contain new data
ax.set_xlim((x[0], x[-1]))
#This shows newly set xdata and ydata on the plot
fig.canvas.draw()
#You need to use plt.pause otherwise the plot won't show up
plt.pause(0.001)
time.sleep(delay)
#Just another variable I used to generate new data
t += 1
See this link for the whole tutorial.
I have been trying to plot live data (data that keeps on updating) using FuncAnimation from the MatplotLib module. When I run the program, the graph doesn't display. The program doesn't give any errors, but displays the following message when I run the program: "Figure size 576x396 with 0 Axes"
Here's my code to plot the live data:
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.animation import FuncAnimation
%matplotlib inline
plt.style.use('seaborn')
def animate(i):
df = pd.read_csv('data2.csv')
x = df['x_value']
y1 = df['total1']
y2 = df['total2']
plt.cla()
plt.plot(x, y1, label='Line1')
plt.plot(x, y2, label = 'Line2')
plt.legend(loc='upper left')
plt.tight_layout()
ani = FuncAnimation(plt.gcf(), animate, interval=1000)
plt.tight_layout()
plt.show()
Here's the csv file I created for the program:
import random
import csv
import time
import pandas as pd
x_value = 0
total1 = 10000
total2 = 10000
fieldnames = ['x_value','total1','total2']
with open('data2.csv', 'w') as csv_file:
csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
csv_writer.writeheader()
while True:
with open('data2.csv','a') as csv_file:
csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
info = {
'x_value': x_value,
'total1' : total1,
'total2' : total2
}
csv_writer.writerow(info)
print(x_value, total1, total2)
x_value += 1
total1 = total1 + random.randint(-6,8)
total2 = total2 + random.randint(9,11)
time.sleep(1)
Any recommendations will be greatly appreciated.
The message, <Figure size 576x396 with 0 Axes> , is showing the location where the graph is saved. Removing plt.show() shows the plot.
I have code that produces a live graph, updating every few seconds. It all functions EXACTLY as I want other than a single issue, the x axis keeps adding new values but never removing old ones
in the example code below, because I limit the dataframe to 6 columns, I expect to never see more than 6 measurements represented on my x-axis. Instead, the graph continues to update and eventually the poiunts are too close together.
from matplotlib import pyplot
from matplotlib.animation import FuncAnimation
import pandas as pd
from datetime import datetime
import threading
import random
import time
measurements = ['abc','bcd','afr','reg','wow']
counter = 0
figure = pyplot.figure()
measurement_frame = pd.DataFrame(index = measurements)
def get_live(counter2, col_num):
measurement_frame.iat[counter2,col_num] = random.randint(50,80)
def add_to_dataframe():
global measurement_frame
#timey = datetime.now().strftime('%H:%M:%S')
timey = datetime.now().time()
if measurement_frame.shape[1] == 6:
measurement_frame.drop(measurement_frame.columns[0], axis = 1, inplace = True)
measurement_frame[timey] = measurements
col_num = measurement_frame.shape[1]-1
print(col_num)
counter2 = 0
for item in measurements:
t = threading.Thread(target=get_live, args=(counter2, col_num,))
t.start()
counter2 = counter2 +1
t.join()
print(measurement_frame.columns[0])
time.sleep(1)
def update(frame):
add_to_dataframe()
x_data = measurement_frame.columns
print(x_data[0])
y1_data = measurement_frame.loc[measurement_frame.index[0]]
y2_data = measurement_frame.loc[measurement_frame.index[1]]
y3_data = measurement_frame.loc[measurement_frame.index[2]]
y4_data = measurement_frame.loc[measurement_frame.index[3]]
y5_data = measurement_frame.loc[measurement_frame.index[4]]
line, = pyplot.plot_date(x_data, y1_data, '-', color = 'b')
line2, = pyplot.plot_date(x_data, y2_data, '-', color = 'g')
line3, = pyplot.plot_date(x_data, y3_data, '-', color = 'r')
line4, = pyplot.plot_date(x_data, y4_data, '-', color = 'm')
line5, = pyplot.plot_date(x_data, y5_data, '-', color = 'y')
line.set_data(x_data, y1_data)
line2.set_data(x_data, y2_data)
line3.set_data(x_data, y3_data)
line4.set_data(x_data, y4_data)
line5.set_data(x_data, y5_data)
figure.gca().set_xlim(x_data[0])
figure.gca().autoscale()
print(figure.gca().get_xlim())
return line, line2, line3, line4, line5,
animation = FuncAnimation(figure, update, interval=1000)
pyplot.show()
What I need is that after the dataframe reaches maximum size, the far left measurements are removed, so as to not exceed a set number of measurements on the screen at once. Note that the dataframe already drops unneeded columns before adding a new one when it reaches a certain size, but my graph does not reflect that
using autoscale tries to keep old data in view. If you drop autoscale and use
figure.gca().set_xlim(left =x_data[0], right = datetime.now().time())
it works as intended
the full code is now
from matplotlib import pyplot
from matplotlib.animation import FuncAnimation
import pandas as pd
from datetime import datetime
import threading
import random
import time
measurements = ['abc','bcd','afr','reg','wow']
counter = 0
figure = pyplot.figure()
measurement_frame = pd.DataFrame(index = measurements)
def get_live(counter2, col_num):
measurement_frame.iat[counter2,col_num] = random.randint(50,80)
def add_to_dataframe():
global measurement_frame
#timey = datetime.now().strftime('%H:%M:%S')
timey = datetime.now().time()
if measurement_frame.shape[1] == 6:
measurement_frame.drop(measurement_frame.columns[0], axis = 1, inplace = True)
measurement_frame[timey] = measurements
col_num = measurement_frame.shape[1]-1
print(col_num)
counter2 = 0
for item in measurements:
t = threading.Thread(target=get_live, args=(counter2, col_num,))
t.start()
counter2 = counter2 +1
t.join()
print(measurement_frame.columns[0])
time.sleep(1)
def update(frame):
add_to_dataframe()
x_data = measurement_frame.columns
print(x_data[0])
y1_data = measurement_frame.loc[measurement_frame.index[0]]
y2_data = measurement_frame.loc[measurement_frame.index[1]]
y3_data = measurement_frame.loc[measurement_frame.index[2]]
y4_data = measurement_frame.loc[measurement_frame.index[3]]
y5_data = measurement_frame.loc[measurement_frame.index[4]]
line, = pyplot.plot_date(x_data, y1_data, '-', color = 'b')
line2, = pyplot.plot_date(x_data, y2_data, '-', color = 'g')
line3, = pyplot.plot_date(x_data, y3_data, '-', color = 'r')
line4, = pyplot.plot_date(x_data, y4_data, '-', color = 'm')
line5, = pyplot.plot_date(x_data, y5_data, '-', color = 'y')
line.set_data(x_data, y1_data)
line2.set_data(x_data, y2_data)
line3.set_data(x_data, y3_data)
line4.set_data(x_data, y4_data)
line5.set_data(x_data, y5_data)
figure.gca().set_xlim(left =x_data[0], right = datetime.now().time())
print(figure.gca().get_xlim())
return line, line2, line3, line4, line5,
animation = FuncAnimation(figure, update, interval=1000)
pyplot.show()
I have been trying to create a live plot by matplotlib.
My trial code is this.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import time
from PySide import QtCore
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
N=100
def animate(j):
graph_data = open('example.txt','r').read()
lines = graph_data.split('\n')
xs=[]
ys=[]
for line in lines:
if len(line) > 1:
x,y = line.split(',')
xs.append(float(x))
ys.append(float(y))
ax.clear()
ax.plot(xs, ys)
def initFile():
fid = open('example.txt','w')
fid.write('')
fid.close()
for i in range(0,N):
fid = open('example.txt', 'a')
fid.write(str(i) + ',' + str(0) + '\n')
fid.close()
def updateFile():
global wThread
wThread = writeThread()
wThread.start()
class writeThread(QtCore.QThread):
def __init__(self, parent=None):
QtCore.QThread.__init__(self, parent)
self.exiting = False
def run(self):
i=0
while 1:
fid = open('example.txt', 'a')
fid.write(str(N+i) + ',' + str(np.sin(2*np.pi*0.05*i)) + '\n')
time.sleep(0.1)
i=i+1
fid.close()
initFile()
updateFile()
ani = animation.FuncAnimation(fig, animate, interval = 200)
plt.show()
It works well. But, the plot points are accumulated. I want to keep up the number of points in my plot as N.
How could I do that?
Simply restrict the size of your array/list to the last N points:
def animate(j):
(...)
ax.clear()
ax.plot(xs[-N:], ys[-N:])