python animation
Posted: Thu Jan 17, 2019 3:43 pm
I have a gauge animation indicating the power received. Ideally it should work in real-time. But, after initializing it and expecting it to change value as the program proceeds , I am stuck because the stimulations won't start until I close the figure(which was supposed to change values as the program proceeds). The code is below. I do not know how to get it to work in real-time. Also, is it possible for the figure to appear as part of the visualization window and not separately, it will be so convenient if this is possible for matplotlib figures to be embedded into the main visualization window:
Code: Select all
import os, sys
import matplotlib
from matplotlib import cm
from matplotlib import pyplot as plt
import numpy as np
import matplotlib.animation as animation
import time
from matplotlib.patches import Circle, Wedge, Rectangle
# let's define a new box class that inherits from OVBox
class MyOVBox(OVBox):
def __init__(self):
OVBox.__init__(self)
# we add a new member to save the signal header information we will receive
self.signalHeader = None
self.threshold=0
#stores the current chunk at anytime
self.chunk=[0]
self.fig,self.ax=plt.subplots()
def initialize(self):
self.threshold=float(self.setting['Threshold'])
ani=animation.FuncAnimation(self.fig,self.animate,interval=30)
plt.show()
def animate(self,i):
if (self.chunk[0]<=0.33*self.threshold):
self.ax.clear()
self.gauge(1)
elif (self.chunk[0]<=0.66*self.threshold) and (self.chunk[0]>0.33*self.threshold):
self.ax.clear()
self.gauge(2)
elif (self.chunk[0]<=self.threshold) and (self.chunk[0]>0.66*self.threshold):
self.ax.clear()
self.gauge(3)
elif (self.chunk[0]<=1.33*self.threshold) and (self.chunk[0]>self.threshold):
self.ax.clear()
self.gauge(4)
elif (self.chunk[0]<1.66*self.threshold) and (self.chunk[0]>1.33*self.threshold):
self.ax.clear()
self.gauge(5)
else :
self.ax.clear()
self.gauge(6)
def degree_range(self,n):
start = np.linspace(0,180,n+1, endpoint=True)[0:-1]
end = np.linspace(0,180,n+1, endpoint=True)[1::]
mid_points = start + ((end-start)/2.)
return np.c_[start, end], mid_points
def rot_text(self,ang):
rotation = np.degrees(np.radians(ang) * np.pi / np.pi - np.radians(90))
return rotation
def gauge(self,arrow=1):
#fixed stuff
labels=['LOW','MEDIUM','HIGH','VERY HIGH','EXTREME','CRITICAL']
colors='YlOrRd_r'
title='ERD level'
N = len(labels)
#if colors is a string, we assume it's a matplotlib colormap and we discretize in N discrete colors
if isinstance(colors, str):
cmap = cm.get_cmap(colors, N)
cmap = cmap(np.arange(N))
colors = cmap[::-1,:].tolist()
if isinstance(colors, list):
if len(colors) == N:
colors = colors[::-1]
else:
raise Exception("\n\nnumber of colors {} not equal to number of categories{}\n".format(len(colors), N))
ang_range, mid_points = self.degree_range(N)
labels = labels[::-1]
patches =[]
for ang, c in zip(ang_range, colors):
# sectors
patches.append(Wedge((0.,0.), .4, *ang, facecolor='w', lw=2))
# arcs
patches.append(Wedge((0.,0.), .4, *ang, width=0.10, facecolor=c, lw=2, alpha=0.5))
[self.ax.add_patch(p) for p in patches]
#set the labels (e.g. 'LOW','MEDIUM',...)
for mid, lab in zip(mid_points, labels):
self.ax.text(0.35 * np.cos(np.radians(mid)), 0.35 * np.sin(np.radians(mid)), lab, horizontalalignment='center', verticalalignment='center', fontsize=14, fontweight='bold', rotation = self.rot_text(mid))
#set the bottom banner and the title
r = Rectangle((-0.4,-0.1),0.8,0.1, facecolor='w', lw=2)
self.ax.add_patch(r)
self.ax.text(0, -0.05, title, horizontalalignment='center',verticalalignment='center', fontsize=22, fontweight='bold')
#Arrow
pos = mid_points[abs(arrow - N)]
self.ax.arrow(0, 0, 0.225 * np.cos(np.radians(pos)), 0.225 * np.sin(np.radians(pos)),width=0.04, head_width=0.09, head_length=0.1, fc='k', ec='k')
self.ax.add_patch(Circle((0, 0), radius=0.02, facecolor='k'))
self.ax.add_patch(Circle((0, 0), radius=0.01, facecolor='w', zorder=11))
#removes frame and ticks, and makes axis equal and tight
self.ax.set_frame_on(False)
self.ax.axes.set_xticks([])
self.ax.axes.set_yticks([])
self.ax.axis('equal')
plt.tight_layout()
def process(self):
for chunkIndex in range( len(self.input[0]) ):
if(type(self.input[0][chunkIndex]) == OVSignalBuffer):
self.chunk=self.input[0].pop()
elif(type(self.input[0][chunkIndex]) == OVSignalEnd):
print 'Signal end reached'
else:
self.chunk=self.input[0].pop()
# Finally, we notify openvibe that the box instance 'box' is now an instance of MyOVBox.
# Don't forget that step !!
box = MyOVBox()