core-extra/daemon/core/gui/dialogs/graphs.py

127 lines
3.5 KiB
Python

import logging
import random
import tkinter as tk
from tkinter import ttk
import numpy as np
from matplotlib.animation import FuncAnimation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
from core.gui.dialogs.dialog import Dialog
from core.gui.themes import PADY
class GraphDialog(Dialog):
def __init__(self, app, title, live=False):
super().__init__(app, title, modal=False)
self.fig = None
self.plot = None
self.canvas = None
self.toolbar = None
self.animation = None
self.live = live
def draw(self):
self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1)
# create figure and plot
frame = ttk.Frame(self.top)
frame.grid(sticky="nsew", pady=PADY)
self.fig = Figure(figsize=(6, 5), dpi=100)
self.plot = self.fig.add_subplot(111)
# create and draw figure canvas
self.canvas = FigureCanvasTkAgg(self.fig, master=frame)
self.canvas.draw()
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
# create and draw toolbar
self.toolbar = NavigationToolbar2Tk(self.canvas, frame)
self.toolbar.update()
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
# initialize graph artists
self.init_artists()
def run(self):
logging.info("live graph")
self.animation = FuncAnimation(
fig=self.fig, func=self.animate, interval=1000, repeat_delay=5000
)
def show(self):
self.draw()
if self.live:
self.run()
super().show()
def init_artists(self):
raise NotImplementedError
def animate(self, frame, *fargs):
raise NotImplementedError
class GraphLineDialog(GraphDialog):
def __init__(self, app, title, live=False):
super().__init__(app, title, live)
self.x_data = []
self.y_data = []
self.line = None
self.background = None
def init_artists(self):
self.plot.set_ylim(0, 10)
self.line, = self.plot.plot(self.x_data, self.y_data)
if self.live:
self.background = self.canvas.copy_from_bbox(self.plot.bbox)
def animate(self, frame, *fargs):
logging.info("blit graph counter: %s - %s", frame, fargs)
x = frame
y = random.randint(1, 10)
self.x_data.append(x)
self.y_data.append(y)
self.line.set_data(self.x_data, self.y_data)
# restore background
self.plot.relim()
self.plot.axes.autoscale_view(True, True, True)
self.canvas.restore_region(self.background)
self.plot.draw_artist(self.line)
self.canvas.blit(self.plot.bbox)
class GraphBarDialog(GraphDialog):
def __init__(self, app, title):
super().__init__(app, title)
def init_artists(self):
data = (20, 35, 30, 35, 27)
ind = np.arange(5)
width = 0.5
return self.plot.bar(ind, data, width)
def animate(self, frame, *fargs):
pass
def animate_blit(self, frame, *fargs):
pass
class GraphScatterDialog(GraphDialog):
def __init__(self, app, title):
super().__init__(app, title)
def init_artists(self):
t = np.arange(0, 3, 0.01)
return self.plot.scatter(t, 2 * np.sin(2 * np.pi * t))
def animate(self, frame, *fargs):
pass
def animate_blit(self, frame, *fargs):
pass