0

I am creating a realtime plot in matplotlib, hpwever I cannot get the x axis to update the ticks in realtime, what I want to do is have the time of occurence on each tick, for example if the ticks were set up to 5 minute intervals it would be 10:20,10:25,10:30,etc. What Im currently doing doesn't work, i append new times to the array and then call the array to the xtick. array:

self.datetime1 = time.localtime()
self.datetime1 = timeString  = time.strftime("%m-%d %H:%M:%S", self.datetime1)
self.date.append(self.datetime1)

xticks:

self.ax1.set_xticklabels(self.date)
5
  • Do you have to change the xticks or can you just rescale the axis? Commented Aug 28, 2012 at 20:35
  • I have to change the xticks, because the axis is in realtime. Commented Aug 28, 2012 at 20:44
  • Maybe I am not understanding the question. What are you trying to plot (i.e. what does the data look like)? Are you trying to create a "scrolling" plot that only shows a 5 minute window? Finally, as I understand it, set_xticklabels will just change the text labels, not change the x-axis scale Commented Aug 28, 2012 at 20:51
  • Okay, what I have is a realtime plot and it goes on until the user exits the program, the plot is a line-plot, if you are windows take a look at the task manager/performance, my plot is similar to the plots in their, except I want add the time on the xticks. Commented Aug 28, 2012 at 21:00
  • So basically you want a moving plot with some defined time range with time on the x axis? I'll try putting somehting together. Commented Aug 28, 2012 at 22:55

1 Answer 1

1

Let me know if this makes sense to you. I put this example together, it is not the prettiest. I think the key is to use the plot_time(ars...) to tell matplotlib to look for numbers and format correctly.

Using python[2.7.2], matplotlib, numpy:

import numpy as np
from matplotlib import pyplot as plt
import random, sys
from datetime import datetime, timedelta
import time

tWindow=1 #moving window in minutes

timeList=[datetime.now()]
valList=[random.randint(1, 20)]

fig = plt.figure() #Make a figure
ax = fig.add_subplot(111) #Add a subplot

#Create the line with initial data using plot_date to add time to the x axis
line,=plt.plot_date(timeList, valList, linestyle='-') 

#Set the x limits to the time window
ax.set_xlim([datetime.now()-timedelta(seconds=tWindow*60),datetime.now()])

#set the y limits
ax.set_ylim(0,20)

#grab the blank background to clear the plot later
background = fig.canvas.copy_from_bbox(ax.bbox)

#show the figure
fig.show()

#loop
for i in range(100):
    #restore the background
    fig.canvas.restore_region(background)

    #add time to time list
    timeList.append(datetime.now())

    #add random value to values
    valList.append(random.randint(1, 20))

    #update the line data
    line.set_data(timeList,valList)

    #update x limits
    ax.set_xlim([datetime.now()-timedelta(seconds=tWindow*60),datetime.now()])

    #redraw widnow
    fig.canvas.draw()

    #pause the loop for .5 seconds
    time.sleep(0.5)

Produces: code output

Update:

I just found your other post with the code I guess you are working on.

Try replacing

self.l_user, = self.ax.plot([],self.user, label='Total %')

With

self.l_user, = self.ax.plot_date([],self.user, label='Total %')

Now you can pass timestamps to matplotlib so instead of

def timerEvent(self, evt):
        # get the cpu percentage usage
        result = self.get_cpu_usage()
        # append new data to the datasets
        self.user.append(result[0])
        # update lines data using the lists with new data
        self.l_user.set_data(range(len(self.user)), self.user)
        # force a redraw of the Figure
        self.fig.canvas.draw()
           #else, we increment the counter
        self.cnt += 1

Try doing something along the lines of

def timerEvent(self, evt):
        # get the cpu percentage usage
        result = self.get_cpu_usage()
        # append new data to the datasets
        self.user.append(result[0])
        #save the current time
        self.timeStamp.append(datetime.now())
        # update lines data using the lists with new data
        self.l_user.set_data(self.timeStamp, self.user)
        #rescale the x axis maintaining a 5 minutes window
        self.ax.set_xlim([datetime.now()-timedelta(seconds=5*60),datetime.now()])
        # force a redraw of the Figure, this might not update the x axis limits??
        self.fig.canvas.draw()
           #else, we increment the counter
        self.cnt += 1

with the appropriate imports and variable initialization

from datetime import datetime, timedelta

class CPUMonitor(FigureCanvas):
    """Matplotlib Figure widget to display CPU utilization"""
    def __init__(self):
        ...
        self.timeStamp=[]
        ...
Sign up to request clarification or add additional context in comments.

3 Comments

@user1582983, so the code I posted above works on my machine (windows, python 2.7.2, matplotlib, etc..). so what are you doing differently? (BTW the more details you provide, the better your responses)
it gives me an error, dt = datetime.datetime.fromordinal(ix) ValueError: ordinal must be >= 1
@user1582983, Your welcome, I am glad it works! Does the y axis change scales with time? I am not sure if self.fig.canvas.draw() would update that as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.