0

I am trying to plot real time data. I managed to plot the data but I would like for the bar graph to go up and down on a single x-value rather than produce new x-values for every new datapoint. I believe I have to replace the function x.append(i) with something like a replace, any ideas? Thank you!!

So far this is what I came up with:

import time
import psutil
import matplotlib.pyplot as plt
%matplotlib notebook

fig = plt.figure()
ax = fig.add_subplot(111)
fig.show()
plt.axis('off')

i = 0
x, y = [], []

while True:
    x.append(i)
    y.append(psutil.cpu_percent())
    
    ax.bar(x, y, color='b')
    
    fig.canvas.draw()
    
    ax.set_xlim(left=max(0, i-50), right=i+50)
    
    time.sleep(0.1)
    i += 1
Mark
  • 90,562
  • 7
  • 108
  • 148

2 Answers2

0

For the bar graph you can create a list inside the while loop, and instantly update it there. First you need to import a random in order get random value for y axis, or you can use cpu_percent.

import psutil 
import random

These two should work. And then:

while True: 
    x_axis = [str(_) for _ in range(100, 200)]
    y_axis = [8 * random.random() for _ in range(100, 200)]
    ax.bar(x, y, color='b')
    fig.canvas.draw()
    time.sleep(0.1)

However, matplotlib is not convenient for real data plotting, I strongly recommend you to use bokeh. You can find bokeh documentation here. It is really cool for creating any kind of real time plot. And at the same time, you can integrate it with your web browser. Hope this will help you)

KiraCoder
  • 1
  • 3
  • Thank you! Very useful resources (: – Researchderp Aug 24 '21 at 17:27
  • Unfortunately, I receive the following error: --------------------------------------------------------------------------- NameError Traceback (most recent call last) /tmp/ipykernel_526/3961775249.py in 9 x_axis = [str(_) for _ in range(100, 200)] 10 y_axis = [8 * random.random() for _ in range(100, 200)] ---> 11 ax.bar(x, y, color='b') 12 fig.canvas.draw() 13 time.sleep(0.1) NameError: name 'x' is not defined – Researchderp Aug 24 '21 at 17:47
  • Have you tried my second option, that should work. Bokeh is very comfortable for streaming data. – KiraCoder Aug 25 '21 at 01:26
0

If you just want to display the latest value, you can consider doing something like:

plt.ion()
graph = plt.bar(["Now"], [0])[0]
plt.axis('off')

i = 0
data = {}

while True:

    cpu_percent = psutil.cpu_percent()
    
    graph.set_ydata(cpu_percent)
    plt.draw()
    plt.pause(0.1)

    data[i] = cpu_percent 
    i += 1

This way, you still have a record of all the datapoints to play with later (x, y) but you will only display 1 x value at a time on the graph.

Further reading

PeptideWitch
  • 2,239
  • 14
  • 30
  • 1
    Thank you! I do get the following error though: AttributeError Traceback (most recent call last) /tmp/ipykernel_184/3640181601.py in 10 cpu_percent = psutil.cpu_percent() 11 ---> 12 graph.set_ydata(cpu_percent) 13 plt.draw() 14 plt.pause(0.1) AttributeError: 'Rectangle' object has no attribute 'set_ydata' – Researchderp Aug 24 '21 at 17:43
  • Can you try `graph.set_height(cpu_percent)` instead of `graph.set_ydata(cpu_percent)`? – PeptideWitch Aug 25 '21 at 01:35