%  File man/render.animation.Rd in package ndtv, part of the Statnet suite
%  of packages for network analysis, http://statnet.org .
%
%  This software is distributed under the GPL-3 license.  It is free,
%  open source, and has the attribution requirements (GPL Section 7) at
%  http://statnet.org/attribution
%
%  Copyright 2012-2016 Statnet Commons
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\name{render.animation}
\alias{render.animation}
%- Also NEED an '\alias' for EACH other topic documented here.
\title{
Render animations of \code{networkDynamic} objects as movies in various formats
}
\description{
Takes a network object which describes a sequence of changes in properties of a network and graphically renders it out as a sequence of plots to create an animation. Normally the coordinates determining the vertex positions at specified time points should have been calculated and stored in the network object, along with the \code{slice.par} list of parameters describing when and how the network should be divided up in time. If the coordinate data is not found, \code{\link{compute.animation}} will be called with default arguments.

Appropriate `static' networks for each time region will be generated by \code{network.collapse}.  The rendering of each frame is drawn by \link[network]{plot.network} and most arguments are supported and are passed through to control the details of rendering. The rendered images are stored using the \code{\link[animation]{animation}} package and can be played in the plot window (\code{\link[animation]{ani.replay}}) or saved to a movie file with \code{\link[animation]{saveVideo}}.
}
\usage{
render.animation(net, render.par = list(tween.frames = 10, show.time = TRUE, 
            show.stats = NULL, extraPlotCmds=NULL, initial.coords=0),
            plot.par = list(bg='white'), ani.options = list(interval=0.1), 
            render.cache = c('plot.list','none'), verbose=TRUE, ...)
}
%- maybe also 'usage' for other objects documented here.
\arguments{
  \item{net}{
The networkDynamic object to be rendered, usually containing pre-computed vertex positions as dynamic attributes. 
}
  \item{render.par}{
Named list of parameters to specify the behavior of the animation.
  \itemize{
  \item \code{tween.frames} the number of interpolated frames to generate between each calculated network layout (default 10). 
  \item \code{show.time} If \code{TRUE}, labels the plot with onset and terminus time for each slice. 
  \item \code{show.stats} \code{NULL}, or a string containing a formula to be passed to summary.stergm to display the network statistics for the current slice on the plot. e.g. \code{"~edges+gwesp(0,fixed=TRUE)"}
  \item \code{extraPlotCmds} NULL, or additional plot commands to draw on each frame of the animation. 
  \item \code{initial.coords} default initial coords to be assigned to vertices. Can be a two-column numeric coordinate matrix, or a numeric values to be formed into a matrix.
  }
}
 \item{plot.par}{
   list of `high-level' plotting control arguments to be passed to \code{\link{par}}. e.g. \code{bg} for background color, margins, fonts, etc. 
 }
 \item{ani.options}{
  list of control arguments for the animation library. For example. \code{interval} controls the delay between frames in playback, \code{ani.dev} and \code{ani.type} can be used to set non-default graphics devices for rendering (i.e \code{'jpeg'} instead of \code{'png'}). See \code{\link[animation]{ani.options}}
 }
 \item{render.cache}{ the default value of \code{'plot.list'} causes each frame of the animation to be cached in an internal list by the \code{\link[animation]{ani.record}} function of the \code{animation} library. This is very useful for testing and replaying animations in R's plot window, but can be very slow (or cause out-of-memory errors) for large animations. If the value is set to \code{'none'}, the plot will not be recorded (but can be saved to disk via \code{\link[animation]{saveVideo}}, see examples below) and cannot be replayed via the \code{ani.replay()} function.    
 }
\item{verbose}{
 If \code{TRUE}, update text will be printed to the console to report the status of the rendering process.
}
  \item{...}{
 Other parameters to control network rendering. See \code{\link[network]{plot.network.default}}. Most parameters can be set to TEA attribute names, or specified as a function to be evaluated at each timestep }
 
}
  
  
\details{

Most of the network plotting arguments are passed directly to \code{\link[network]{plot.network.default}}.  All of the \code{\link[network]{plot.network}} arguments pased in via ... can be specified as a TEA or special type of function to be evaluated at each time step.  For example, if there was a dynamic vertex attribute named 'wealth', it could be mapped to vertex size by providing the TEA name \code{vertex.cex='wealth'}. If the wealth value needed transformation to be an appropriate vertex size, it can be specified as a function: \code{vertex.cex=function(slice){slice\%v\%'wealth'*5-3}}

The arguments of plot control functions must draw from a specific set of named arguments which will be substituted in and evaluated at each time point before plotting.  The set of valid argument names is:
\itemize{
  \item \code{net} is the original (uncollapsed) network
  \item \code{slice} is the network collapsed with the appropriate onset and terminus
  \item \code{s} is the slice number
  \item \code{onset} is the onset (start time) of the slice to be rendered
  \item \code{terminus} is the terminus (end time) of the slice to be rendered
}

A few of the plot parameters have defaults that are different from the ones given by \code{\link[network]{plot.network}}:
\itemize{
  \item \code{jitter} defaults to \code{FALSE} to prevent unwanted bouncing
  \item \code{xlim} and \code{ylim} default to the ranges of the entire set of network coordinates.  Although they can be set to function values for interesting effects...
  \item \code{xlab} defaults to a function to display the time range: \code{function(onset,terminus){paste("t=",onset,"-",terminus,sep='')}}. It also will be overidden if \code{show.stats} is set. 
}

If no \code{slice.par} network attribute is found to define the time range to render,  it will make one up using the smallest and largest non-Inf time values, unit-length non-overlapping time steps and an aggregation rule of 'latest'. 

If no dynamic coordinate information has been stored, \code{\link{compute.animation}} will be called with default values to try to do the layout before giving up. 

Additional plot commands passed in via the \code{extraPlotCmds} argument will be  passed to \code{eval()} after each frame is rendered and can be used to add extra annotations to the plot. 

One some installations, the default output from \verb{saveVideo()} (really ffmpeg) produces videos in a slightly non-standard .mp4 format that won't play in Windows Media Player or QuickTime.  Users have reported that adding the argument \verb{other.opts='-pix_fmt yuv420p"} to \verb{saveVideo} corrects the problem. Recent versions of the \verb{animation} library will include this argument by default.  

To avoid performance issues with the RStudio graphics device, RStudio users will see a message that ndtv is attempting to open another type of plot window.  It will try to guess a platform-appropriate device type, but specific device can be pre-specified by the user by setting the \code{R_DEFAULT_DEVICE} environment variable
}

\note{
A few of the network drawing arguments have slightly different interpretations than their \link[network]{plot.network} equivalents:
\itemize{
\item \code{xlab} will be used to display time and network statistics if those \code{render.par} parameters are set
\item \code{xlim} and \code{ylim} will be set using max and min observed coordinate values so that all network slices will appear on the plot

\item \code{label} if not set explicitly, will default to the vertex names for the appropriate slice network. 
}
If the background color is transparent and not explicitly set, it will be reset to white to prevent unintentional behavior when exporting movies via ffmpeg. 


}

\value{
A sequence of plots will be generated on the active plot device. If \code{render.cache='plot.list'} the recorded plots are stored as a list in \code{.ani.env$.images}. }
\references{
Skye Bender-deMoll and McFarland, Daniel A. (2006) The Art and Science of Dynamic Network Visualization. \emph{Journal of Social Structure. Volume 7, Number 2} \url{https://www.cmu.edu/joss/content/articles/volume7/deMollMcFarland/}
}
\author{
Skye Bender-deMoll, and the statnet team. 
}



\seealso{
\code{\link{compute.animation}} for generating the movie coordinates, \code{\link[animation]{ani.replay}}, \code{\link[network]{plot.network}} and the package vignette \code{vignette('ndtv')}. Also \code{\link{render.d3movie}} for displaying movies as interactive HTML5 animations in a web browser
}
\examples{

require(ndtv)
# trivial example

triangle <- network.initialize(3) # create a toy network
add.edge(triangle,1,2)
# add an edge between vertices 1 and 2
add.edge(triangle,2,3)
# add a more edges
activate.edges(triangle,at=1) # turn on all edges at time 1 only
activate.edges(triangle,onset=2, terminus=3,
e=get.edgeIDs(triangle,v=1,alter=2))
add.edges.active(triangle,onset=4, length=2,tail=3,head=1)
render.animation(triangle)
ani.replay() 

# an example with changing TEA attributes
wheel <- network.initialize(10)  # create a toy network
add.edges.active(wheel,tail=1:9,head=c(2:9,1),onset=1:9, terminus=11)
add.edges.active(wheel,tail=10,head=c(1:9),onset=10, terminus=12)
# set a dynamic value for edge widths
activate.edge.attribute(wheel,'width',1,onset=0,terminus=3) 
activate.edge.attribute(wheel,'width',5,onset=3,terminus=7)
activate.edge.attribute(wheel,'width',10,onset=3,terminus=Inf)
# set a value for vertex sizes
activate.vertex.attribute(wheel,'mySize',1, onset=-Inf,terminus=Inf)
activate.vertex.attribute(wheel,'mySize',3, onset=5,terminus=10,v=4:8)
# set values for vertex colors
activate.vertex.attribute(wheel,'color','gray',onset=-Inf,terminus=Inf)
activate.vertex.attribute(wheel,'color','red',onset=5,terminus=6,v=4)
activate.vertex.attribute(wheel,'color','green',onset=6,terminus=7,v=5)
activate.vertex.attribute(wheel,'color','blue',onset=7,terminus=8,v=6)
activate.vertex.attribute(wheel,'color','pink',onset=8,terminus=9,v=7)
# render it all
render.animation(wheel,edge.lwd='width',vertex.cex='mySize',vertex.col='color')


# an example with functional attributes
set.network.attribute(wheel,'slice.par',
           list(start=1,end=10,interval=1, aggregate.dur=1,rule='latest'))
# render vertex size as betweeness
render.animation(wheel,vertex.cex=function(slice){(betweenness(slice)+1)/5})


# render it directly to a movie file without caching the plots (faster)
\dontrun{
saveVideo( render.animation(wheel,edge.lwd='width',vertex.cex='mySize',vertex.col='color',
           render.cache='none') )
}

# simulation based example
# disabled to save time when testing
\dontrun{
require(tergm)
# load in example data, results of a basic stergm sim
data(stergm.sim.1)

# (optional) pre-compute coordinates for set time range
# (optional) limit time range to a few steps to speek example
slice.par=list(start=0,end=10,interval=1, aggregate.dur=1,rule='latest')
compute.animation(stergm.sim.1,slice.par=slice.par)


# define the number of inbetween frames and a formula for stats to display
render.par<-list(tween.frames=5,show.time=TRUE,
                show.stats="~edges+gwesp(0,fixed=TRUE)")
                
# render the movie, with labels, smaller vertices, etc
render.animation(stergm.sim.1,render.par=render.par,
                 edge.col="darkgray",displaylabels=TRUE,
                 label.cex=.6,label.col="blue")
                 
# preview the movie in the plot window
ani.replay()     

# save the movie as mp4 compressed video (if FFMPEG installed)
saveVideo(ani.replay(),video.name="stergm.sim.1.mp4", 
           other.opts="-b 5000k",clean=TRUE)
}

}

