I'm trying to plot the exponents of 2 vs the 2 to the power of the exponent but I keep getting a linear graph instead of the curve. I'm not sure what I'm doing wrong.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from random import seed
from random import random
import math
tiktok=0
#Desired style
style.use('dark_background')
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
T= open('live_graphText.txt','w+')
T.truncate(0)
T.close()
test = f=open('live_graphText.txt','w+')
for i in range(10):
test.write("%d,%d\n"%(i,math.pow(2,i)))
tiktok = tiktok+i
test.close()
In addition I'm trying to use the live graph animation from matplotlib.animation with a file i created. to keep automatically keep adding points to the file but it seems the function isn't even being called. I'm not sure if I just have it called in the wrong place or the function just doesn't make sense
#This is not being called
def edit(tik):
global tiktok
f=open('live_graphText.txt','a+')
f.write("%d,%d\n"%(tik,math.pow(2,tik)))
print("HelloWorld")
tiktok = tiktok +1
f.close()
def animate(i):
#Opening the file to read
graph_data = open('live_graphText.txt','r').read()
#Split the lines by \n
lines=graph_data.split('\n')
xs =[]
ys =[]
for line in lines:
#This if statement ignores any white space at the end of the file
if len(line)>1:
x,y = line.split(',')
xs.append(x)
ys.append(y)
#print(xs)
#print(ys)
ax1.clear()
ax1.plot(xs,ys)
#The parameters are (Where to plot the function, the function we are plotting, the interval we want to plot in milliseconds)
ani = animation.FuncAnimation(fig,animate,interval=1000)
plt.show()
while tiktok<20:
edit(tiktok)
print(tiktok)
plt.show()
Any help is appreciated!
Related
My task is to plot a numpy array in real time using matplotlib. Please note that I don't want to use animation function to do this.
import numpy as np
import time
from matplotlib.lines import Line2D
import matplotlib
class Plot:
def __init__(self,f,axis,data):
self.fig = f
self.axis = axis
self.data = data
def plotting(self,i):
xs = [self.data[i,0],self.data[i+1,0]]
ys = [self.data[i,1],self.data[i+1,1]]
line, = self.axis.plot(xs,ys,'g-')
self.fig.canvas.draw()
data = np.random.rand(10,2) #numpy array
f = plt.figure()
axis = f.add_axes([0,0,0.9,0.9])
plotData = Plot(f,axis,data)
for i in range(len(data)-1):
plotData.plotting(i)
time.sleep(1)
plt.show()
But everytime I run this code it returns me one empty figure. How do I rectify it?
import matplotlib.pyplot as plt
import numpy as np
# use ggplot style for more sophisticated visuals
plt.style.use('ggplot')
def live_plotter(x_vec,y1_data,line1,identifier='',pause_time=0.1):
if line1==[]:
# this is the call to matplotlib that allows dynamic plotting
plt.ion()
fig = plt.figure(figsize=(13,6))
ax = fig.add_subplot(111)
# create a variable for the line so we can later update it
line1, = ax.plot(x_vec,y1_data,'-o',alpha=0.8)
#update plot label/title
plt.ylabel('Y Label')
plt.title('Title: {}'.format(identifier))
plt.show()
# after the figure, axis, and line are created, we only need to update the y-data
line1.set_ydata(y1_data)
# adjust limits if new data goes beyond bounds
if np.min(y1_data)<=line1.axes.get_ylim()[0] or np.max(y1_data)>=line1.axes.get_ylim()[1]:
plt.ylim([np.min(y1_data)-np.std(y1_data),np.max(y1_data)+np.std(y1_data)])
# this pauses the data so the figure/axis can catch up - the amount of pause can be altered above
plt.pause(pause_time)
# return line so we can update it again in the next iteration
return line1
A few notes on the function above:
line1.set_ydata(y1_data) can also be switched to line1.set_data(x_vec,y1_data) to change both x and y data on the plots.
plt.pause() is necessary to allow the plotter to catch up - I've been able to use a pause time of 0.01s without any issues
The user will need to return line1 to control the line as it is updated and sent back to the function
The user can also customize the function to allow dynamic changes of title, x-label, y-label, x-limits, etc.
This Python program plots lines dynamically from data in a csv file. When the program first starts it dynamically draws points that already exist in the file. This part works as expected. I'd like for any new points added to the file to be subsequently drawn. The problem is that i continues to increment so by the time a new item is added to my csv file the value of i is usually much higher than the index from the csv so it never gets plotted. How can I prevent the count of i continuing on until there is an applicable value in the csv file?
import numpy as np
from itertools import count
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
plt.style.use('fivethirtyeight')
data = pd.read_csv('csv_data.csv')
x_vals = []
y_vals1 = []
y_vals2 = []
index = count()
def animate(i):
x = data['x_value']
y1 = data['total_1']
y2 = data['total_2']
x_vals.append(x[i])
y_vals1.append(y1[i])
y_vals2.append(y2[i])
plt.cla()
plt.plot(x_vals, y_vals1, label='Channel 1')
plt.plot(x_vals, y_vals2, label='Channel 2')
plt.legend(loc='upper left')
plt.tight_layout()
ani = FuncAnimation(plt.gcf(), animate, interval=100)
plt.show()
I'm plotting real-time data using parsed data from a file that is being repeatedly opened. I'm deriving and plotting two different values on the same chart. The Y axis scales up and down according the values of each. The "snr" (green) value is plotting fine but the "data_rate"(red) value seems to be static. See screenshot.
import matplotlib.pyplot as plt
import csv
import datetime
from matplotlib.animation import FuncAnimation
import numpy as np
x = []
y = []
z = []
rssi_val = []
def animate(i):
with open('stats.txt', 'r') as searchfile:
time = (searchfile.read(8))
for line in searchfile:
if 'agrCtlRSSI:' in line:
rssi_val = line[16:20]
rssi_val=int(rssi_val)
if 'agrCtlNoise:' in line:
noise_val = (line[16:20])
noise_val=int(noise_val)
if 'maxRate:' in line:
data_rate = (line[16:20])
data_rate=int(data_rate)
snr = ((noise_val - rssi_val) * -1)
#begin test
y.append(snr)
x.append(time)
z.append(data_rate)
#end test
#begin test
plt.cla()
#Verify values are not empty
print("SNR = ", snr)
print("DR = ", data_rate)
plt.plot(snr,label='Signal')
plt.plot(data_rate,label='Data Rate')
plt.legend(loc='upper right')
plt.plot(x,y,z)
ax=plt.gca()
ax.tick_params('x',labelrotation=60)
#end test
ani = FuncAnimation(plt.gcf(), animate, interval=1000)
plt.show()
The simplest way is to call plot twice.
plt.plot(x,y)
plt.plot(x,z)
See "Plotting multiple sets of data" here for more options.
I’m going to preface this by saying that I am still learning Python so please be kind and patient. My code goes as follows:
Client on the network sends a text file (stats.txt) every ~5 seconds to an SCP server. Python code sits on the server.
Code below begins:
import matplotlib.pyplot as plt
import csv
import datetime
x = []
y = []
rssi_val = []
def animate(i):
with open('stats.txt', 'r') as searchfile:
time = (searchfile.read(5))
for line in searchfile:
if 'agrCtlRSSI:' in line:
rssi_val = line[16:20]
y = [rssi_val]
x = [time for i in range(len(y))]
plt.xlabel('Time')
plt.ylabel('RSSI')
plt.title('Real time signal strength seen by client X')
#plt.legend()
plt.plot(x,y)
ani = FuncAnimation(plt.gcf(), animate, interval=5000)
plt.tight_layout()
#plt.gcf().autofmt_xdate()
plt.show()
SCP server opens the file every 5 seconds and plots the values that are parsed from the file. Time gets plotted on the X axis and the RSSI value gets plotted on the Y axis.
I understand that the code and methods used are not efficient at this point and will be modified in the future. For now I simply want the the plot values to show up and the chart to be animated with the plot (line) every 5 or so seconds.
Running it produces nothing.
You need to have the line
ani = FuncAnimation(plt.gcf(), animate, interval=5000)
Outside of the function animate, then assuming the data are received and read in properly you should see the plot updating. You may also need to put plt.show() after the FuncAnimation() line depending on how you are executing the script.
Edit
You may want to try something like this instead
import matplotlib.pyplot as plt
import csv
import datetime
x = []
y = []
rssi_val = []
def animate(i):
with open('stats.txt', 'r') as searchfile:
time = (searchfile.read(5))
for line in searchfile:
if 'agrCtlRSSI:' in line:
rssi_val = line[16:20]
y.append(rssi_val)
x.append(time)
plt.cla()
plt.plot(x,y)
plt.xlabel('Time')
plt.ylabel('RSSI')
plt.title('Real time signal strength seen by client X')
plt.tight_layout()
ani = FuncAnimation(plt.gcf(), animate, interval=5000)
plt.show()
I want to plot data in matplotlib in real time. I want to open a figure once at the start of the programme, then update the figure when new data is acquired. Despite there being a few similar questions out there, none quite answer my specific question.
I want each set of data points new_data1 and new_data2 to be plotted on the same figure at the end of each while loop i.e. one line after the first while loop, two lines on the same figure after the second while loop etc. Currently they are all plotted together, but only right at the end of the programme, which is no use for real time data acquisition.
import matplotlib.pyplot as plt
import numpy
hl, = plt.plot([], [])
def update_line(hl, new_datax, new_datay):
hl.set_xdata(numpy.append(hl.get_xdata(), new_datax))
hl.set_ydata(numpy.append(hl.get_ydata(), new_datay))
plt.xlim(0, 50)
plt.ylim(0,200)
plt.draw()
x = 1
while x < 5:
new_data1 = []
new_data2 = []
for i in range(500):
new_data1.append(i * x)
new_data2.append(i ** 2 * x)
update_line(hl, new_data1, new_data2)
x += 1
else:
print("DONE")
This programme plots all 5 lines, but at the end of the programme. I want each line to be plotted after one another, after the while loop is completed. I have tried putting in plt.pause(0.001) in the function, but it has not worked.
This programme is different from the one that has been put forward - that programme only plots one graph and does not update with time.
If I correctly understood your specifications, you can modify just a bit your MWE as follows:
import matplotlib.pyplot as plt
import numpy
fig = plt.figure(figsize=(11.69,8.27))
ax = fig.gca()
ax.set_xlim(0, 50)
ax.set_ylim(0,200)
hl, = plt.plot([], [])
def update_line(hl, new_datax, new_datay):
# re initialize line object each time if your real xdata is not contiguous else comment next line
hl, = plt.plot([], [])
hl.set_xdata(numpy.append(hl.get_xdata(), new_datax))
hl.set_ydata(numpy.append(hl.get_ydata(), new_datay))
fig.canvas.draw_idle()
fig.canvas.flush_events()
x = 1
while x < 10:
new_data1 = []
new_data2 = []
for i in range(500):
new_data1.append(i * x)
new_data2.append(i ** 2 * x)
update_line(hl, new_data1, new_data2)
# adjust pause duration here
plt.pause(0.5)
x += 1
else:
print("DONE")
which displays :
Not sure, if I am reading the requirements right but below is a blueprint. Please change it to suit your requirements. You may want to change the function Redraw_Function and edit the frames (keyword parameter, which is np.arange(1,5,1) ) in the FuncAnimation call. Also interval=1000 means 1000 milliseconds of delay.
If you are using Jupyter then comment out the second last line (where it says plt.show()) and uncomment the last line. This will defeat your purpose of real time update but I am sorry I had trouble making it work real time in Jupyter. However if you are using python console or official IDLE please run the code as it is. It should work nicely.
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
plot, = plt.plot([],[])
def init_function():
ax.set_xlim(0,50)
ax.set_ylim(0,250)
return plot,
def Redraw_Function(UpdatedVal):
new_x = np.arange(500)*UpdatedVal
new_y = np.arange(500)**2*UpdatedVal
plot.set_data(new_x,new_y)
return plot,
Animated_Figure = FuncAnimation(fig,Redraw_Function,init_func=init_function,frames=np.arange(1,5,1),interval=1000)
plt.show()
# Animated_Figure.save('MyAnimated.gif',writer='imagemagick')
When you run the code, you obtain the below result. I tried to keep very little code but I am sorry, if your requirement was totally different.
Best Wishes,