Source code for bvhsdk.gui.main

# Author: https://stackoverflow.com/questions/36665850/matplotlib-animation-inside-your-own-gui
###################################################################
#                                                                 #
#                     PLOTTING A LIVE GRAPH                       #
#                  ----------------------------                   #
#            EMBED A MATPLOTLIB ANIMATION INSIDE YOUR             #
#            OWN GUI!                                             #
#                                                                 #
###################################################################


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as matplotanim
import matplotlib.gridspec as gridspec
from matplotlib.widgets import Button, TextBox
from .. import anim
import time

#My imports
from mpl_toolkits.mplot3d import Axes3D


[docs] def start(animation): assert type(animation) == anim.Animation GUIPlayer(animation)
#print('Computing positions...') #all_frames_bones_data = [] #for frame in animation.frames: # all_frames_bones_data.append(animation.getBones(frame))
[docs] class GUIPlayer(): #def Plot3DAnimation(animation): """ Plot animation as skeleton :type animation: Animation class object :param animation: Animation to be draw """ def __init__(self, animation): self.animation = animation fig = plt.figure(figsize=(12,8)) ax = fig.add_subplot(111, projection='3d') self.play = True self.forward = True self.current_frame = 0 self.current_fps = 0 self.count_frame = 0 self.count_frame_time = time.time() self.lines = [] #maxdata = -np.inf #mindata = np.inf bones = animation.getBones(frame = 0) for bone in bones: self.lines.append( ax.plot([ bone[0], bone[3] ], [ bone[1], bone[4] ], [ bone[2], bone[5] ]) ) ax.set_xlim( (-150,150) ) ax.set_ylim( (-50,200) ) ax.set_zlim( (-150,150) ) self.fps_text = ax.text(x= ax.get_xlim()[1]-1, y= ax.get_ylim()[1]-1, z=0, s=str(self.current_fps)) #for joint in animation.getlistofjoints(): # position = joint.getPosition(frame = 0) # scatters.append(ax.plot([position[0]],[position[1]],[position[2]],'o', color='red', markersize=1)[0]) # if np.min(position)<mindata: # mindata = np.min(position) # if np.max(position)>maxdata: # maxdata = np.max(position) ax.view_init(elev=100, azim=-90) ax.set_xlabel('X axis') ax.set_ylabel('Y axis') ax.set_zlabel('Z axis') #ax.set_xlim(mindata,maxdata) #ax.set_ylim(mindata,maxdata) #ax.set_zlim(mindata,maxdata) axes_framedisplaytext = fig.add_axes([0.6, 0.05, 0.05, 0.05]) axes_onebackward = fig.add_axes([0.65, 0.05, 0.05, 0.05]) #[left, bottom, width, height] axes_backward = fig.add_axes([0.7, 0.05, 0.05, 0.05]) #[left, bottom, width, height] axes_pause = fig.add_axes([0.75, 0.05, 0.05, 0.05]) axes_forward = fig.add_axes([0.8, 0.05, 0.05, 0.05]) axes_oneforward = fig.add_axes([0.85, 0.05, 0.05, 0.05]) self.textbox_framedisplay = TextBox(axes_framedisplaytext, label='frame', initial='0') self.button_oneback = Button(axes_onebackward, label='$\u29CF$') self.button_backward = Button(axes_backward, label='$\u25C0$') self.button_pause = Button(axes_pause, label='$\u2016$') self.button_forward = Button(axes_forward, label='$\u25B6$') self.button_oneforw= Button(axes_oneforward, label='$\u29D0$') self.textbox_framedisplay.on_submit(self.onchange_textbox_framedisplay) self.button_oneback.on_clicked(self.click_onebackward) self.button_backward.on_clicked(self.click_backward) self.button_pause.on_clicked(self.click_pause) self.button_forward.on_clicked(self.click_forward) self.button_oneforw.on_clicked(self.click_oneforward) #ani = matplotanim.FuncAnimation(fig, self.update, frames=np.arange(animation.frames), fargs=([self.lines]) ,interval=1, blit=False) ani = matplotanim.FuncAnimation(fig, self.update, frames=self.funcplay(), fargs=() ,interval=1, blit=False) plt.show() #return ani
[docs] def onchange_textbox_framedisplay(self, event): try: self.current_frame = int(self.textbox_framedisplay.text) except: self.textbox_framedisplay.set_val( str(self.current_frame) )
[docs] def click_oneforward(self, event): self.current_frame += 1 self.play = True
[docs] def click_onebackward(self, event): self.current_frame -= 1 self.play = True
[docs] def click_backward(self, event): self.forward = False self.play = True
[docs] def click_pause(self, event): self.play = not self.play
[docs] def click_forward(self, event): self.forward = True self.play = True
[docs] def funcplay(self): while True: if self.play: self.current_frame += self.forward - (not self.forward) if self.current_frame > self.animation.frames: self.current_frame = 0 yield self.current_frame
[docs] def update(self, frame): time1 = time.time() # TODO: maybe not the best way to skip update during pause if self.play: print(frame) if self.count_frame == 10: delta = time.time()-self.count_frame_time self.fps_text.set_text(s="fps: {0:.2f}".format( 10 / (delta))) self.count_frame = 0 self.count_frame_time = time.time() self.count_frame += 1 self.textbox_framedisplay.set_val( str(frame) ) bones = self.animation.getBones(frame) for line, bone in zip(self.lines,bones): line[0].set_data([ bone[0], bone[3] ], [ bone[1], bone[4] ]) line[0].set_3d_properties( [bone[2], bone[5]]) return self.lines
[docs] def showinfo(animation): assert type(animation) == anim.Animation gui = GUIShowInfo(animation) return gui
[docs] class GUIShowInfo(): def __init__(self, animation): self.animation = animation #fig, axs = plt.figure(3, 3, figsize=(12,8)) fig = plt.figure(figsize=(12,8), tight_layout=True) gs = gridspec.GridSpec(3, 3, figure=fig) positions = np.empty(shape=(len(animation.getlistofjoints()), 3)) offsets = np.empty(shape=(len(animation.getlistofjoints()), 3)) for i, joint in enumerate(animation.getlistofjoints()): positions[i] = joint.getPosition(frame = 0) offsets[i] = joint.offset axs = [] lab = {0: 'X axis', 1: 'Y axis', 2: 'Z axis'} for i in range(3): xyz = [[0,1], [1,2], [0,2]][i] axs.append(fig.add_subplot(gs[i, 1])) axs[-1].scatter(positions[:,xyz[0]], positions[:,xyz[1]], c='r', marker='o') axs[-1].set_aspect('equal') axs[-1].set_xlabel(lab[xyz[0]]) axs[-1].set_ylabel(lab[xyz[1]]) axs = [] for i in range(3): xyz = [[0,1], [1,2], [0,2]][i] axs.append(fig.add_subplot(gs[i, 2])) axs[-1].scatter(offsets[:,xyz[0]], positions[:,xyz[1]], c='r', marker='o') axs[-1].set_aspect('equal') axs[-1].set_xlabel(lab[xyz[0]]) axs[-1].set_ylabel(lab[xyz[1]]) axs.append(fig.add_subplot(gs[:, 0])) for i, joint in enumerate(animation.root.printHierarchy()): axs[-1].text(0, -i*0.1, str(i) + " " + joint, fontsize=10) axs[-1].set_ylim(-len(animation.getlistofjoints())*0.1, 0.1) axs[-1].set_axis_off() plt.show()