59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""
|
|
Helper class to track length of time taken for each frame and draw a graph when application exits.
|
|
Also able to add events at arbitrary times across the graph.
|
|
"""
|
|
import time
|
|
import matplotlib.pyplot as plt
|
|
import statistics
|
|
|
|
|
|
class FrametimePlotter:
|
|
EVENT_POINT_Y = -0.05
|
|
EVENT_MSG_Y = -0.045
|
|
|
|
def __init__(self):
|
|
self.times = []
|
|
self.events = []
|
|
self.start = time.perf_counter()
|
|
|
|
def add_event(self, event_msg):
|
|
self.events.append((len(self.times), event_msg))
|
|
|
|
def end_frame(self, time_delta):
|
|
self.times.append(time_delta)
|
|
|
|
def _show_stats(self):
|
|
end = time.perf_counter()
|
|
print("Min : {:.5f}".format(min(self.times)))
|
|
print("Max : {:.5f}".format(max(self.times)))
|
|
print("Avg : {:.5f}".format(statistics.mean(self.times)))
|
|
print("Median: {:.5f}".format(statistics.median(self.times)))
|
|
try:
|
|
print("Mode : {:.5f}".format(statistics.mode(self.times)))
|
|
except statistics.StatisticsError as e:
|
|
print("Mode : {}".format(e))
|
|
print("StdDev: {:.5f}".format(statistics.stdev(self.times)))
|
|
frame_count = len(self.times)
|
|
elapsed_time = end - self.start
|
|
print("Frame count: {}".format(frame_count))
|
|
print("Elapsed time: {:.5f}".format(elapsed_time))
|
|
print("FPS: {:.5f}".format(frame_count / elapsed_time))
|
|
|
|
def show(self):
|
|
if len(self.times) <= 1:
|
|
return
|
|
self._show_stats()
|
|
frame_idxs = range(0, len(self.times))
|
|
event_idxs = [e[0] for e in self.events]
|
|
event_point_y = [self.EVENT_POINT_Y] * len(self.events)
|
|
plt.figure("Frame durations", figsize=(8, 6))
|
|
plt.plot(frame_idxs, self.times, event_idxs, event_point_y, "k|")
|
|
plt.xlabel("frames")
|
|
plt.ylabel("frame duration")
|
|
plt.ylim(self.EVENT_POINT_Y - 0.005, 0.5)
|
|
plt.tight_layout()
|
|
for frame_idx, msg in self.events:
|
|
plt.text(frame_idx, self.EVENT_MSG_Y, msg, horizontalalignment="center", verticalalignment="bottom",
|
|
size="smaller", rotation="vertical")
|
|
plt.show()
|