Gary Gary - 1 year ago 162
Python Question

Generating a Real-Time Plot with matplotlib and an updating text file

I am trying to generate a real-time plot of data using the

animation
function from
matplotlib
. I am referring to this tutorial from the following link for my support: Realtime Plotting in MatPlotLib

The
data.txt
file that I am reading in, is being updated every second with new data. The data coming in looks as follows:
[0.0263671875, 0.03515625, 1.0087890625][0.01171875, 0.0146484375, 0.4404296875][0.01171875, 0.0146484375, 0.4404296875]
... and so on.

The first three lines of the animate function are extracting the third element in each array:

data = pd.read_csv("C:\\Users\\Desktop\\data.txt", sep="\[|\]\[|\]",engine = 'python', header = None)
data = data.iloc[0]
data = data.astype(str).apply(lambda x: x.split(',')[-1]).astype(float)
data.pop(0)


I verified this code in Jupyter notebook and the output is as follows (and is what I am looking for):
enter image description here

My first challenge comes from when I am trying to generate the graph in real-time. My data doesn't have an x-axis (for time). So, one of my first hurdles is that to generate an artificial x-axis as the data stream updates. The code from the above linked tutorial was used as the template. I will point out the areas where I am struggling to modify for my specific purpose.

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

def animate(i):
data = pd.read_csv("C:\\Users\\Desktop\\data.txt", sep="\[|\]\[|\]",engine = 'python', header = None)
data = data.iloc[0]
data = data.astype(str).apply(lambda x: x.split(',')[-1]).astype(float)
data.pop(0)
xar = []
yar = []
for eachLine in data:
if len(eachLine)>1:
x,y = eachLine.split(',')
xar.append(int(x))
yar.append(int(y))
ax1.clear()
ax1.plot(xar,yar)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()


In addition to artificially creating x-axis numbers so that I can create the plot, I also need to modify the for loop:

xar = []
yar = []
for eachLine in data:
if len(eachLine)>1:
x,y = eachLine.split(',')
xar.append(int(x))
yar.append(int(y))


In the example provided in the link, their data stream has an
x
and
y
data point, separated by a column. The data stream that I have, is just one value.

How would I modify my code to (1) add a proper x-axis to be able to plot and (2) properly go through the for loop in order to append the values to the
xar
and
yar
to plot the graph in real-time.

EDIT 1
I tried the following, but it doesn't work and needs some help... but it's my first shot. I am getting the error:

if len(eachLine)>1:

TypeError: object of type 'numpy.float64' has no len()


And my code is as follows:

def animate(i):
data = pd.read_csv("C:\\Users\\Desktop\\data.txt", sep="\[|\]\[|\]",engine = 'python', header = None)
data = data.iloc[0]
data = data.astype(str).apply(lambda x: x.split(',')[-1]).astype(float)
data.pop(0)
xar = []
yar = []
for j in range(len(data)):
xar.append(j)
for k in range(len(data)):
yar.append(data.iloc[k])
for eachLine in data:
if len(eachLine)>1:
x,y = eachLine.split('')
xar.append(int(x))
yar.append(int(y))
ax1.clear()
ax1.plot(xar,yar)
ani = animation.FuncAnimation(fig, animate, interval=1)
plt.show()


Thank you!

Answer Source

Not having a clue about the data that is read in makes it hard to understand the problem. However in general you would plot a column from a dataframe as follows

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

def animate(i):
    data = pd.read_csv(...)
    yar = data[ "column to plot" ]
    xar = range(len(data))
    ax.clear()
    ax.plot(xar,yar)

ani = animation.FuncAnimation(fig, animate, interval=10)
plt.show()
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download