Last data update: 2014.03.03

R: Plots velocities as arrows or as trajectory plots.
Quiver and flow pathsR Documentation

Plots velocities as arrows or as trajectory plots.

Description

Function quiver2D displays velocity vectors as arrows, using ordinary graphics.

Function quiver2Drgl displays velocity vectors as arrows using rgl.

Function flowpath displays the flow paths of particles, based on velocity vectors.

Usage

quiver2D(u, ...)

## S3 method for class 'matrix'
quiver2D(u, v, x = NULL, y = NULL, 
           colvar = NULL, ..., 
           scale = 1, arr.max = 0.2, arr.min = 0, speed.max = NULL,  
           by = NULL, type = "triangle", col = NULL, NAcol = "white", 
           breaks = NULL, colkey = NULL, mask = NULL,
           image = FALSE, contour = FALSE, 
           clim = NULL, clab = NULL, 
           add = FALSE, plot = TRUE) 

## S3 method for class 'array'
 quiver2D(u, v, margin = c(1, 2), subset, ask = NULL, ...)
                    
quiver2Drgl (u, v, x = NULL, y = NULL, colvar = NULL, ..., 
           scale = 1, arr.max = 0.2, arr.min = 0, speed.max = NULL, 
           by = NULL, type = "triangle", 
           col = NULL, NAcol = "white", breaks = NULL,
           mask = NULL, image = FALSE, contour = FALSE,
           colkey = NULL, clim = NULL, clab = NULL, add = FALSE, plot = TRUE)

flowpath(u, v, x = NULL, y = NULL, startx = NULL, starty = NULL, ...,
           scale = 1, numarr = 0, arr.length = 0.2, maxstep = 1000, 
           add = FALSE, plot = TRUE)

Arguments

u

A matrix (quiver2D) or array (quiver2D.array) with velocities in x-direction. For quiver2D the number of rows should be = Nx or Nx+1 (Nx = length(x), if x given), the number of columns should be = Ny or Ny+1 (Ny = length(y), if y given).

v

A matrix (quiver2D) or array (quiver2D.array) with velocities in y-direction. For quiver2D the number of rows should be = Nx or Nx+1, the number of columns should be = Ny or Ny+1.

x

Vector with x-coordinates of the velocities. If NULL, it is taken to be a sequence between (0, 1), and with length = nrow(u).

y

Vector with y-coordinates of the velocities. If NULL, it is taken to be a sequence between (0, 1), and with length = ncol(v).

startx

Vector with the start position in x-direction of the flow paths. Length > =1. If not specified, then all combinations of x and y at the outer margins will be used as starting point.

starty

Vector with start position in y-direction of flow paths. Length = length of startx.

colvar

The variable used for coloring. It need not be present, but if specified, it should be a vector of dimension equal to c(nrow(u), ncol(v)). Values of NULL, NA, or FALSE will toggle off coloration according to colvar.

col

Colors to be used for coloring the arrows as specified by the colvar variable. If col is NULL and colvar is specified, then a red-yellow-blue colorscheme (jet.col) will be used. If col is NULL and colvar is not specified, then col will be "black".

NAcol

Colors to be used for colvar values that are NA.

breaks

a set of finite numeric breakpoints for the colors; must have one more breakpoint than color and be in increasing order. Unsorted vectors will be sorted, with a warning.

scale

Scaling factor for the arrows. When scale = 1, the longest arrow will fill a grid cell in x- and y- direction. When scale = 2, it will be twice as long.

arr.max

Maximal size of the arrowhead, in cm (approximately). The arrows are scaled according to the velocity (sqrt(u^2 + v^2)). arr.max is associated with the maximal velocity.

arr.min

Minimal size of the arrowhead, in cm (approximately). Set arr.min = arr.max for constant size.

speed.max

Speed that corresponds to arr.max. Everything with speed larger than speed.max will be depicted with size equal to arr.max. If unspecified (max(sqrt(u^2 + v^2))).

by

Number increment for plotting the vectors; one value or two (x, y) values. For example, setting by = 2 will plot every second velocity value in x and in y direction. Setting by = c(1, 2) will plot all vectors in x and every second vector in y. Useful if the vector density is too high.

colkey

A logical, NULL (default), or a list with parameters for the color key (legend). List parameters should be one of side, plot, length, width, dist, shift, addlines, col.clab, cex.clab, side.clab, line.clab, adj.clab, font.clab and the axis parameters at, labels, tick, line, pos, outer, font, lty, lwd, lwd.ticks, col.box, col.axis, col.ticks, hadj, padj, cex.axis, mgp, tck, tcl, las. The defaults for the parameters are side = 4, plot = TRUE, length = 1, width = 1, dist = 0, shift = 0, addlines = FALSE, col.clab = NULL, cex.clab = par("cex.lab"), side.clab = NULL, line.clab = NULL, adj.clab = NULL, font.clab = NULL) See colkey from package plot3D.

The default is to draw the color key on side = 4, i.e. in the right margin. If colkey = NULL then a color key will be added only if col is a vector. Setting colkey = list(plot = FALSE) will create room for the color key without drawing it. if colkey = FALSE, no color key legend will be added.

type

The type of the arrow head, one of "triangle" (the default) or "simple", which uses R-function arrows.

contour, image

If present, then a contour2D or image2D plot will be added to the quiver plot. They should be a list with arguments for the contour2D or image2D function.

clim

Only if colvar is specified, the range of the colors, used for the color key.

clab

Only if colkey is not NULL or FALSE, the label to be written on top of the color key. The label will be written at the same level as the main title. To lower it, clab can be made a vector, with the first values empty strings.

margin

A vector giving the subscripts which the plotting function will be applied over. The plotting function will loop over the index that is not in margin. For instance, c(1, 2), indicates to plot rows(x) and columns(y) and to loop over index 3; c(2, 1) will do the same but transposed. margin should be a vector with two numbers inbetween 1, and 3.

ask

A logical; if TRUE, the user is asked before each plot, if NULL the user is only asked if more than one page of plots is necessary and the current graphics device is set interactive, see par(ask) and dev.interactive.

add

If TRUE, will add to current plot. Else will start a new plot. Note: to use this in a consistent way, the previous plot should have been done with one of the plot3D functions.

mask

A matrix or list defining the grid cells outside the domain as NA. Use a list with argument NAcol to specify the color that the masked cells (that are NA) should get; the default is "black". The unmasked cells are left "white".

If x and y are a vector, then mask can be a matrix with dimension equal to length(x), length(y). If either x or y is itself a matrix, then mask should be a list that contains the x, y, and z values (and that are named 'x', 'y', 'z'). A mask cannot be combined with add = TRUE.

plot

If FALSE, will not plot the flow paths, but will return the matrix with path values instead.

numarr

The number of arrows added on the flow paths.

arr.length

Constant size of the arrowhead, in cm (approximately).

maxstep

Maximum number of steps for calculating the flow paths.

...

Additional arguments passed to the plotting methods (arrows2D), The arguments after ... must be matched exactly.

subset

A logical expression indicating over which elements to loop; missing values are taken as FALSE.

Details

S3 function quiver2D plots vectors specified by u, v at the coordinates x, y.

flowpath uses the velocities u, v at the coordinates x, y to create trajectories, starting at points startx, starty. It can also be used to return the flow path points by setting plot equal to FALSE. It uses very simple Euler integration and may not be very accurate.

Value

flowpath returns (as invisible) a 2-column matrix with the x-y coordinates of the flow paths. Separate flow paths are separated with NA.

quiver2D returns (as invisible) a list containing the coordinates of the arrows (x0, x1, y0, y1), the color of each arrow (col), the length of the arrowhead (length) and the maximal speed corresponding to arr.max (speed.max). This output can be used e.g. with function arrows.

Note

There was a slight error in the scaling of the arrows in versions previous to 1.0.3, which has been corrected. See last example.

See Also

arrows3D for an arrows function from package plot3D.

vectorplot for plotting velocity vectors as spikes.

Arrows for the arrow function from package shape on which quiver2D is based.

Examples

## =======================================================================
##  EXAMPLE 1: 
## =======================================================================
 pm <- par("mfrow")
 par(mfrow = c(2, 2))

# generate velocities
 x  <- seq(-1, 1, by = 0.2)
 y  <- seq(-1, 1, by = 0.2)
 dx <- outer(x, y , function(x, y) -y)
 dy <- outer(x, y , function(x, y) x)

# velocity plot, with legend
 F <- quiver2D(u = dx, v = dy, x = x, y = y)
 legend("topright", bg = "white", 
   legend = paste("max = ", format(F$speed.max, digits = 2))) 

# different color for up/downward pointing arrows
 quiver2D(u = dx, v = dy, x = x, y = y, colvar = dx > 0, 
        col = c("red", "blue"), colkey = FALSE,
        arr.max = 0.4, arr.min = 0.1)

# different scale
 quiver2D(u = dx, v = dy, x = x, y = y, by = 2, scale = 2)

# three flow paths
 flowpath(u = dx, v = dy, x = x, y = y, startx = 0.1, starty = 0.1)
 flowpath(u = dx, v = dy, x = x, y = y, 
          startx = c(0.9, -0.9), starty = c(0.0, 0.0), col = "red",
          numarr = 2, add = TRUE)

## =======================================================================
##  EXAMPLE 2: note: has changed in version 1.0.3 - uses contour2D!
## =======================================================================
 par(mfrow = c(1, 1))
 x <- seq(-2, 2, by = 0.2)
 y <- seq(-1, 1, by = 0.2)
 z <- outer (x, y, function(x, y) x^3 - 3*x -2*y^2)
 contour2D(x, y, z = z, col = jet.col(10))

# gradients in x- and y-direction (analytical)
 dX <- outer(x, y, function(x,y) 3*x^2 - 3)
 dY <- outer(x, y, function(x,y) -4*y)

 quiver2D(u = dX, v = dY, x = x, y = y, scale = 1, add = TRUE, by = 1)
 flowpath(u = dX, v = dY, x = x, y = y, startx = c(-2, 1.1), 
            starty = c(-1, -1), add = TRUE, arr.length = 0.5,
            col = "darkgreen", lwd = 3, numarr = 1)

## =======================================================================
##  EXAMPLE 3: 
## =======================================================================
 
 x <- y <- 1:20
 u <- outer (x, y, function (x, y) cos(2*pi*y/10))
 v <- outer (x, y, function (x, y) cos(2*pi*x/10))

 quiver2D(x = x, y = y, u = u, v = v, col = "grey")

# flowpaths using all combinations of x and y at edges
 flowpath(x = x, y = y, u = u, v = v, add = TRUE, 
          lwd = 2, col = "orange")

## =======================================================================
##  EXAMPLE 4: quiver of an array.. 
## =======================================================================
 
 x <- y <- 1:20
 u2 <- outer (x, y, function (x, y) sin(2*pi*y/10))
 v2 <- outer (x, y, function (x, y) sin(2*pi*x/10))

# merge u, u2 and v, v2 to create an "array"
 U <- array(dim = c(dim(u2), 2), data = c(u, u2))
 V <- array(dim = c(dim(v2), 2), data = c(v, v2))

 quiver2D(u = U, v = V, x = x, y = y, main = c("time 1", "time 2"))

# quiver over x and time, for a subset of y-values:
 quiver2D(u = U, v = V, x = x, y = 1:2, 
        margin = c(1, 3), main = paste("y ", y), 
        subset = y <= 4)

## Not run: 
 quiver2D(u = U, v = V, x = x, y = y, ask = TRUE, 
        mfrow = c(1, 1))

 quiver2D(u = U, v = V, x = x, y = 1:2, ask = TRUE, 
        margin = c(1, 3), main = paste("y ", y),
        mfrow = c(1, 1))


## End(Not run)

## =======================================================================
##  EXAMPLE 5: 
## =======================================================================
 par(mfrow = c(1, 1))

 image2D(x = 1:nrow(volcano), y = 1:ncol(volcano), 
       z = volcano, contour = TRUE)

# Assume these are streamfunctions, we calculate the velocity field as:
 dx <- dy <- 1
 v <-   (volcano[-1, ] - volcano[-nrow(volcano), ] )/dx
 u <- - (volcano[, -1] - volcano[ ,-ncol(volcano)] )/dy

 quiver2D(x = 1:nrow(u), y = 1:ncol(v), 
        u = u, v = v, add = TRUE, by = 3)
 
 flowpath(x = 1:nrow(u), y = 1:ncol(v), numarr = 10,
          u = u, v = v, add = TRUE, lwd = 2, col = "grey", 
          startx = 20, starty = 30)
 
## =======================================================================
##  EXAMPLE 6: boundary mask, images, contours
## =======================================================================
 par (mfrow = c(2, 2))
 
 mask <- volcano; mask[volcano < 120]  <- NA
 quiver2D(by = c(3, 2), u = u, v = v, mask = mask)

 quiver2D(by = c(3, 2), u = u, v = v,  
        image = list(z = mask, NAcol = "black"))

 quiver2D(by = c(4, 3), u = u, v = v,
        contour = list(z = volcano, lwd = 2))

 quiver2D(by = c(4, 3), u = u, v = v, 
        contour = list(z = volcano, col = "black"), 
        image = list(z = volcano, NAcol = "black"))

## =======================================================================
##  Same in rgl
## =======================================================================
## Not run: 
 quiver2Drgl(by = c(3, 2), u = u, v = v, mask = mask, NAcol = "black")

 quiver2Drgl(by = c(3, 2), u = u, v = v,  
        image = list(z = volcano, NAcol = "black"))

 quiver2Drgl(by = c(4, 3), u = u, v = v, scale = 2,
        contour = list(z = volcano, lwd = 2))

 quiver2Drgl(by = c(4, 3), u = u, v = v, 
        contour = list(z = volcano, col = "black"), 
        image = list(z = volcano, NAcol = "black"))
 cutrgl()
 uncutrgl()

## End(Not run)

## =============================================================================
## 2-D Data set SyltSurf
## =============================================================================

 par(mfrow = c(1, 1))
 with (Syltsurf,
   quiver2D(x = x, y = y, u = u[ , ,2], v = v[ , ,2], 
     xlim = c(5, 20), ylim = c(10, 25), by = 3, 
     main = paste(formatC(time[1]), " hr"), scale = 1.5, 
     image = list(z = depth, x = x, y = y, NAcol = "black", 
                  colkey = TRUE), 
     contour = list(z = depth, x = x, y = y, col = "black",
       drawlabels = FALSE)
     )
  )

## =============================================================================
## 2-D Data set SyltSurf, several time points
## =============================================================================

# now for an array (first and 4th time point only)
 ii <- c(1, 4)
 with (Syltsurf,
   quiver2D(x = x, y = y, u = u[ ,,ii], v = v[ ,,ii], 
     xlim = c(5, 20), ylim = c(10, 25), by = 4, 
     mask = list(z = depth, x = x, y = y, NAcol = "blue"),
     main = paste(formatC(time[ii]), " hr"), scale = 1.5,
     contour = list(z = depth, x = x, y = y, drawlabels = FALSE)
     )
  )



## =============================================================================
## Adding quivers ...
## =============================================================================
x <- 1:2
y <- 1:3
u <- matrix(1:6,2,3)
v <- matrix(6:1,2,3)
 par(mfrow = c(1, 1))

A <- quiver2D(x = x, y = y, u = u, v = v)
B <- quiver2D(x = x, y = y[-1], u = u[,-1], v = v[,-1], col = 2, add = TRUE)
C <- quiver2D(x = x, y = y[-3], u = u[,-3], v = v[,-3], col = 3, add = TRUE)

# restore parameter settings
 par(mfrow = pm)

Results


R version 3.3.1 (2016-06-21) -- "Bug in Your Hair"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> library(OceanView)
Loading required package: plot3D
Loading required package: plot3Drgl
Loading required package: rgl
> png(filename="/home/ddbj/snapshot/RGM3/R_CC/result/OceanView/quiver.Rd_%03d_medium.png", width=480, height=480)
> ### Name: Quiver and flow paths
> ### Title: Plots velocities as arrows or as trajectory plots.
> ### Aliases: quiver2D quiver2D.matrix quiver2D.array quiver2Drgl flowpath
> ### Keywords: hplot
> 
> ### ** Examples
> 
> ## =======================================================================
> ##  EXAMPLE 1: 
> ## =======================================================================
>  pm <- par("mfrow")
>  par(mfrow = c(2, 2))
> 
> # generate velocities
>  x  <- seq(-1, 1, by = 0.2)
>  y  <- seq(-1, 1, by = 0.2)
>  dx <- outer(x, y , function(x, y) -y)
>  dy <- outer(x, y , function(x, y) x)
> 
> # velocity plot, with legend
>  F <- quiver2D(u = dx, v = dy, x = x, y = y)
>  legend("topright", bg = "white", 
+    legend = paste("max = ", format(F$speed.max, digits = 2))) 
> 
> # different color for up/downward pointing arrows
>  quiver2D(u = dx, v = dy, x = x, y = y, colvar = dx > 0, 
+         col = c("red", "blue"), colkey = FALSE,
+         arr.max = 0.4, arr.min = 0.1)
> 
> # different scale
>  quiver2D(u = dx, v = dy, x = x, y = y, by = 2, scale = 2)
> 
> # three flow paths
>  flowpath(u = dx, v = dy, x = x, y = y, startx = 0.1, starty = 0.1)
>  flowpath(u = dx, v = dy, x = x, y = y, 
+           startx = c(0.9, -0.9), starty = c(0.0, 0.0), col = "red",
+           numarr = 2, add = TRUE)
> 
> ## =======================================================================
> ##  EXAMPLE 2: note: has changed in version 1.0.3 - uses contour2D!
> ## =======================================================================
>  par(mfrow = c(1, 1))
>  x <- seq(-2, 2, by = 0.2)
>  y <- seq(-1, 1, by = 0.2)
>  z <- outer (x, y, function(x, y) x^3 - 3*x -2*y^2)
>  contour2D(x, y, z = z, col = jet.col(10))
> 
> # gradients in x- and y-direction (analytical)
>  dX <- outer(x, y, function(x,y) 3*x^2 - 3)
>  dY <- outer(x, y, function(x,y) -4*y)
> 
>  quiver2D(u = dX, v = dY, x = x, y = y, scale = 1, add = TRUE, by = 1)
>  flowpath(u = dX, v = dY, x = x, y = y, startx = c(-2, 1.1), 
+             starty = c(-1, -1), add = TRUE, arr.length = 0.5,
+             col = "darkgreen", lwd = 3, numarr = 1)
> 
> ## =======================================================================
> ##  EXAMPLE 3: 
> ## =======================================================================
>  
>  x <- y <- 1:20
>  u <- outer (x, y, function (x, y) cos(2*pi*y/10))
>  v <- outer (x, y, function (x, y) cos(2*pi*x/10))
> 
>  quiver2D(x = x, y = y, u = u, v = v, col = "grey")
> 
> # flowpaths using all combinations of x and y at edges
>  flowpath(x = x, y = y, u = u, v = v, add = TRUE, 
+           lwd = 2, col = "orange")
> 
> ## =======================================================================
> ##  EXAMPLE 4: quiver of an array.. 
> ## =======================================================================
>  
>  x <- y <- 1:20
>  u2 <- outer (x, y, function (x, y) sin(2*pi*y/10))
>  v2 <- outer (x, y, function (x, y) sin(2*pi*x/10))
> 
> # merge u, u2 and v, v2 to create an "array"
>  U <- array(dim = c(dim(u2), 2), data = c(u, u2))
>  V <- array(dim = c(dim(v2), 2), data = c(v, v2))
> 
>  quiver2D(u = U, v = V, x = x, y = y, main = c("time 1", "time 2"))
> 
> # quiver over x and time, for a subset of y-values:
>  quiver2D(u = U, v = V, x = x, y = 1:2, 
+         margin = c(1, 3), main = paste("y ", y), 
+         subset = y <= 4)
> 
> ## Not run: 
> ##D  quiver2D(u = U, v = V, x = x, y = y, ask = TRUE, 
> ##D         mfrow = c(1, 1))
> ##D 
> ##D  quiver2D(u = U, v = V, x = x, y = 1:2, ask = TRUE, 
> ##D         margin = c(1, 3), main = paste("y ", y),
> ##D         mfrow = c(1, 1))
> ##D 
> ## End(Not run)
> 
> ## =======================================================================
> ##  EXAMPLE 5: 
> ## =======================================================================
>  par(mfrow = c(1, 1))
> 
>  image2D(x = 1:nrow(volcano), y = 1:ncol(volcano), 
+        z = volcano, contour = TRUE)
> 
> # Assume these are streamfunctions, we calculate the velocity field as:
>  dx <- dy <- 1
>  v <-   (volcano[-1, ] - volcano[-nrow(volcano), ] )/dx
>  u <- - (volcano[, -1] - volcano[ ,-ncol(volcano)] )/dy
> 
>  quiver2D(x = 1:nrow(u), y = 1:ncol(v), 
+         u = u, v = v, add = TRUE, by = 3)
>  
>  flowpath(x = 1:nrow(u), y = 1:ncol(v), numarr = 10,
+           u = u, v = v, add = TRUE, lwd = 2, col = "grey", 
+           startx = 20, starty = 30)
>  
> ## =======================================================================
> ##  EXAMPLE 6: boundary mask, images, contours
> ## =======================================================================
>  par (mfrow = c(2, 2))
>  
>  mask <- volcano; mask[volcano < 120]  <- NA
>  quiver2D(by = c(3, 2), u = u, v = v, mask = mask)
> 
>  quiver2D(by = c(3, 2), u = u, v = v,  
+         image = list(z = mask, NAcol = "black"))
> 
>  quiver2D(by = c(4, 3), u = u, v = v,
+         contour = list(z = volcano, lwd = 2))
> 
>  quiver2D(by = c(4, 3), u = u, v = v, 
+         contour = list(z = volcano, col = "black"), 
+         image = list(z = volcano, NAcol = "black"))
> 
> ## =======================================================================
> ##  Same in rgl
> ## =======================================================================
> ## Not run: 
> ##D  quiver2Drgl(by = c(3, 2), u = u, v = v, mask = mask, NAcol = "black")
> ##D 
> ##D  quiver2Drgl(by = c(3, 2), u = u, v = v,  
> ##D         image = list(z = volcano, NAcol = "black"))
> ##D 
> ##D  quiver2Drgl(by = c(4, 3), u = u, v = v, scale = 2,
> ##D         contour = list(z = volcano, lwd = 2))
> ##D 
> ##D  quiver2Drgl(by = c(4, 3), u = u, v = v, 
> ##D         contour = list(z = volcano, col = "black"), 
> ##D         image = list(z = volcano, NAcol = "black"))
> ##D  cutrgl()
> ##D  uncutrgl()
> ## End(Not run)
> 
> ## =============================================================================
> ## 2-D Data set SyltSurf
> ## =============================================================================
> 
>  par(mfrow = c(1, 1))
>  with (Syltsurf,
+    quiver2D(x = x, y = y, u = u[ , ,2], v = v[ , ,2], 
+      xlim = c(5, 20), ylim = c(10, 25), by = 3, 
+      main = paste(formatC(time[1]), " hr"), scale = 1.5, 
+      image = list(z = depth, x = x, y = y, NAcol = "black", 
+                   colkey = TRUE), 
+      contour = list(z = depth, x = x, y = y, col = "black",
+        drawlabels = FALSE)
+      )
+   )
> 
> ## =============================================================================
> ## 2-D Data set SyltSurf, several time points
> ## =============================================================================
> 
> # now for an array (first and 4th time point only)
>  ii <- c(1, 4)
>  with (Syltsurf,
+    quiver2D(x = x, y = y, u = u[ ,,ii], v = v[ ,,ii], 
+      xlim = c(5, 20), ylim = c(10, 25), by = 4, 
+      mask = list(z = depth, x = x, y = y, NAcol = "blue"),
+      main = paste(formatC(time[ii]), " hr"), scale = 1.5,
+      contour = list(z = depth, x = x, y = y, drawlabels = FALSE)
+      )
+   )
> 
> 
> 
> ## =============================================================================
> ## Adding quivers ...
> ## =============================================================================
> x <- 1:2
> y <- 1:3
> u <- matrix(1:6,2,3)
> v <- matrix(6:1,2,3)
>  par(mfrow = c(1, 1))
> 
> A <- quiver2D(x = x, y = y, u = u, v = v)
> B <- quiver2D(x = x, y = y[-1], u = u[,-1], v = v[,-1], col = 2, add = TRUE)
> C <- quiver2D(x = x, y = y[-3], u = u[,-3], v = v[,-3], col = 3, add = TRUE)
> 
> # restore parameter settings
>  par(mfrow = pm)
> 
> 
> 
> 
> 
> dev.off()
null device 
          1 
>