caleb baker
caleb baker

Reputation: 144

I cannot get the x-axis on my graph to format correctly

I am trying to generate a live graph that shows my data as it is being read. I want the X axis to display time in the format of

HH:MM

I found how to do

xaxis.set_major_formatter(mdate.DateFormatter('%H:%M'))

But this doesn't seem to be working.

from tkinter import *
from tkinter import ttk
import time 
import matplotlib
import threading
matplotlib.use("TkAgg")
import queue
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
import matplotlib.dates as mdate
from matplotlib import style

root = Tk()

graphXData = queue.Queue()
graphYData = queue.Queue()

def animate(objData):
    graph.clear()
    graph.plot(list(graphXData.queue), list(graphYData.queue))

graphFigure = Figure(figsize=(5,5), dpi=100)
graph = graphFigure.add_subplot(111)
graph.xaxis.set_major_formatter(mdate.DateFormatter('%H:%M'))
graph.xaxis_date()
canvas = FigureCanvasTkAgg(graphFigure, root)
canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)

for cnt in range (600):
    graphXData.put(matplotlib.dates.epoch2num(time.time()-(600-cnt)))
    graphYData.put(0)

ani = animation.FuncAnimation(graphFigure,animate,interval=1000)

That gives me a full queue of the last 600 seconds as 0. And i'm putting in new data points in as

graphXData.put(matplotlib.dates.epoch2num(time.time())) 

What I get is 0.0XX Where XX is some integer that I don't understand.

EDIT: As requested I made it into a working verified example and the result i get is

enter image description here

Upvotes: 0

Views: 186

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339380

The problem is that you set the formatter to the axes, but call ax.clear() afterwards. This clears the axes and removes the formatter. So from the first animation step on, it'll have the default formatter, which shows numbers.

A useful solution is to not clear the axes at all such that it'll keep its formatter.

from tkinter import *
from tkinter import ttk
import time 
import matplotlib
#matplotlib.use("TkAgg")
import queue
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
import matplotlib.dates as mdate


root = Tk()

graphXData = queue.Queue()
graphYData = queue.Queue()

def animate(objData):
    line.set_data(list(graphXData.queue), list(graphYData.queue))
    ax.relim()
    ax.autoscale_view()

fig = Figure(figsize=(5,5), dpi=100)
ax = fig.add_subplot(111)
ax.xaxis_date()
line, = ax.plot([],[])
ax.xaxis.set_major_formatter(mdate.DateFormatter('%H:%M'))

canvas = FigureCanvasTkAgg(fig, root)
canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)

for cnt in range (600):
    graphXData.put(matplotlib.dates.epoch2num(time.time()-(600-cnt)))
    graphYData.put(0)

ani = animation.FuncAnimation(fig,animate,interval=1000)

root.mainloop()

Upvotes: 1

Related Questions