Open topic with navigation
matplotlib
Matplotlib is a library with a very 'Matlab' like environment for generating publication quality figures. You can output to raster formats (e.g., PNG, TIFF, JPG) immediately in a pop-up window or to vector (e.g, EPS, PS) formats that are saved as files. The style of graphs and syntax for creating them will be very familiar to users of Matlab, especially when combined with the added Python language constructs through NumPy.
Installation
Matplotlib requires the installation of a few 3rd party packages before it can be used with Vizard.
- Install NumPy. If NumPy is not installed the matplotlib installation will fail.
- Install Tkinter. This is an optional component included with the Vizard installer. If you do not have this installed, run the Vizard installer and select and select .
- From the menu, open the Package Manager. Use the tab to locate the matplotlib library and click .
Use matplotlib
Two common ways to use matplotlib with Vizard are to:
- Save data to one of the various file formats supported or display a matplotlib figure using a GUI toolkit (e.g. Tkinter). The limitation of displaying an interactive figure using matplotlib's show() command is that it is a blocking command and Vizard will halt until the window is closed. Saving the figure to a file will not block the Vizard update loop.
- Apply a matplotlib figure as a vizmatplot texture. This method supports real-time plotting without blocking Vizard's update loop.
Example: Save data to file
The following example script creates a graph using Vizard data and saves this to a PDF file:
'''
A matplotlib figure will be saved as a PDF file in the
current directory. Wait for the script to close automatically
after 10 seconds.
'''
import viz
import vizinfo
import viztask
import vizact
viz.setMultiSample(4)
viz.fov(60)
viz.go()
info = vizinfo.InfoPanel()
#set sample rate in hz
SAMPLE_RATE = 60
#set max number of samples
MAX_SIZE_OF_ARRAY = 600
#create arrays to store data and fill with zeros
array_time, array_height = [],[]
for i in range(0,MAX_SIZE_OF_ARRAY):
array_time.append(0)
array_height.append(0)
###---physics simulation---###
viz.phys.enable()
ball = viz.addChild('beachball.osgb', pos=(0,10,6))
ballphys = ball.collideSphere(bounce = 1.5)
ground = viz.addChild('sky_day.osgb')
ground.collidePlane()
#task function that adds to ball height and time arrays every frame
import time
starttime = time.time()
def getData():
for i in range (0,MAX_SIZE_OF_ARRAY):
array_time[i] = time.time() - starttime
array_height[i] = ball.getPosition()[1]
yield viztask.waitTime(1.0/SAMPLE_RATE) #wait at least a frame before setting new data points
#call our task function
data = viztask.schedule(getData())
#take the arrays and create a simple plot of time and ball height and save it as a
#PDF file in the current script directory
from pylab import *
def savePlot():
plot(array_time, array_height, linewidth=1.0)
axis([0,10,0,10])
xlabel('time (s)')
ylabel('height (m)')
title('matplotlib and Vizard')
grid(True)
savefig( "Vizard_Plot.pdf", format='pdf' )
viz.quit()
vizact.ontimer2(10,0,savePlot)
Example: Plot data in real-time
The following example applies a matplotlib figure to a vizmatplot texture and plots data in real-time:
import viz
import vizact
import viztask
import vizmatplot
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
viz.setMultiSample(8)
viz.fov(60)
viz.go()
import vizinfo
vizinfo.InfoPanel('Press the <space bar> to restart the simulation')
# Time duration of plot
PLOT_DURATION = 10.0
# Rate to sample data in hz
SAMPLE_RATE = 60.0
# Rate to redraw plot in hz
REDRAW_RATE = 20.0
# Create arrays to store data
array_time, array_height, array_velocity = [], [], []
# Create a matplotlib figure
fig = plt.figure()
# Create subplot for ball height
ax_height = fig.add_subplot(111) #create axes
ax_height.axis([0,PLOT_DURATION,0,10]) #set axis limits
# Create a subplot for ball velocity
# Make new plot that shares the x-axis with ax_height. the y-axis is independent and have different tick marks on left and right y-axis
ax_velocity = ax_height.twinx()
ax_velocity.axis([0,PLOT_DURATION,-15,15])
# Create yellow line for height plot
line_height, = ax_height.plot(array_time, array_height, 'y')
# Create blue line for velocity plot
line_velocity, = ax_velocity.plot(array_time, array_velocity, 'b')
# Create labels for figure
plt.grid() # Display grid lines
plt.title('Y-Coord and Velocity of Ball')
plt.xlabel('Time in Seconds')
ax_height.set_ylabel('y coord in meters')
ax_velocity.set_ylabel('velocity in meters per sec')
# Create texture for displaying figure
fig_texture = vizmatplot.Texture(fig)
# Create quad to render plot texture
quad = viz.addTexQuad(texture=fig_texture, pos=(0,1.8,1))
quad.alpha(0.5)
# Create simulation models
viz.phys.enable()
ball = viz.addChild('beachball.osgb', pos=(0,10,10))
ball.collideSphere(bounce=1.5)
ground = viz.addChild('ground.osgb')
ground.collidePlane()
# Create global params
params = viz.Data(startTime=viz.tick())
def CollectData():
"""Collects data for plotting"""
elapsed = viz.tick() - params.startTime
if elapsed <= PLOT_DURATION:
array_time.append(elapsed)
array_height.append(ball.getPosition()[1]) #store position data of ball in array
array_velocity.append(ball.getVelocity()[1]) #store velocity data of ball in array
vizact.ontimer(1.0 / SAMPLE_RATE, CollectData)
def PlotTask():
"""Task that updates plot with latest data and redraws texture"""
while True:
yield viztask.waitTime(1.0 / REDRAW_RATE)
elapsed = viz.tick() - params.startTime
if elapsed <= PLOT_DURATION:
# Update plot data
line_height.set_data(array_time, array_height)
line_velocity.set_data(array_time, array_velocity)
# Wait for redraw
yield fig_texture.waitRedraw()
viztask.schedule(PlotTask())
def Reset():
"""Reset plot data and ball position"""
del array_time[:]
del array_height[:]
del array_velocity[:]
ball.setPosition([0,10,10])
ball.reset()
params.startTime = viz.tick()
vizact.onkeydown(' ', Reset)