R/wga_plot.R

Defines functions snp.effects.plot OR.getTitle OR.plot.type OR.plot.type.method OR.plot.main gene.getOrder gene.transform.loc gene.plot.colors gene.plot.main gene.plot save.plot set.plot getColors chrm.plot.ylim addLineSegments chrm.plot.legend chrm.plot.pch chrm.plot.colors getUniqueChrm chrm.plot.main Manhattan.plot transform.loc QQ.plot2 QQ.plot_old0 QQ.plot getLims getFigs setDevice

Documented in Manhattan.plot QQ.plot snp.effects.plot

# History Mar 11 2008  Initial coding
#         Mar 13 2008  Add option to transform the locations 
#         Mar 18 2008  Check for errors in the beginning
#         Mar 27 2008  Add option to split the screen in 2.
#         Apr 08 2008  Add option for the maximum upper limit and
#                      a dashed line.
#         May 13 2008  Add code for UNIX.
#         Jul 25 2008  Add QQ.plot
#         Aug 21 2008  In QQ.plot, plot on -log10 scale
#         Sep 03 2008  Add plotting symbols and colors 
#         Oct 15 2008  Add options for QQ.plot
#         Nov 17 2008  Generalize chromosome.plot
#         Nov 20 2008  Remove missing values in chromosome, for the
#                      chromosome plot function.
#         Nov 25 2008  Add title and legend options in chromosome plot
#         Nov 25 2008  Fix bug with matching snp names in chromosome.plot
#         Mar 17 2009  Add forest.plot function
#                      Change to setDevice
#         Apr 11 2009  Add alternating colors to chromosome plot
#         Apr 27 2009  Allow alternating colors with multiple p-values
#                      in chromsome plot.
#         Apr 29 2009  Allow for character variables in qq, chromosome plot
#         Jul 15 2009  Add optional vec to QQ plot
#         Jul 23 2009  Remove library(rmeta) call in forestPlot
#         Jul 28 2009  Let alt.colors = 1 be default value in chromosome.plot
#                      Move forest.plot to wga_plot2.R
#         Oct 13 2009  Include add option in chromosome.plot
#                      Dashed line option
#                      Add options for padj and las in chromosome.plot
#         Oct 14 2009  Add getColors function
#         Nov 19 2009  Fix bug in chrm.plot.ylim
#         Mar 09 2010  Add functions set.plot and save.plot
#         Mar 15 2010  Add new option to chromosome plot for removing white space
#                      on edges of plot.
#         Mar 23 2010  Add option to not print x-axis label in chromosome.plot
#         Mar 24 2010  Add gene.plot, remove myplot.scan.gwaa and myplot
#         Mar 26 2010  Add OR.plot.main function
#         Apr 26 2010  Add confidence intervals to OR.plot
#         May 03 2010  Add title option and list of sublists of options for OR.plot
#         Sep 23 2010  Add QQ.plot2 function for qq-plots using -2log(pval)
#         Jan 31 2011  Add wrapper function for gene.plot for perm package
#         Nov 04 2011  Fix OR.plot for 1 method, length(levels2)=1
#         Nov 15 2011  Change name of OR.plot to effects.plot
#         Jun 15 2015  Add new QQ.plot function
#         Jun 17 2015  Update chromosomePlot function
#         Sep 11 2015  Rename chromosome.plot to Manhattan.plot

# Function to set a graphics device
setDevice <- function(file, op=NULL) {

  # file     NULL or file to save plot
  ###############################################################
  # op
  #  type    "jpeg", "ps" or "pdf"
  #          The default is "jpeg"
  #  which   0 or 1  0=before plot, 1 = after plot
  #          The default is 0

  if (is.null(file)) return(NULL)

  op   <- default.list(op, c("type", "which"), list("jpeg", 0))
  type <- tolower(op$type)

  winFlag <- (.Platform$OS.type == "windows")

  if (op$which == 0) {
    if (winFlag) {
      return(0)
    }
    if (type == "ps") {
      postscript(file)
    } else if (type == "pdf") {
      pdf(file)
    } else {
      jpeg(file)
    } 
  } else {
    if (!winFlag) {
      graphics.off()
    } else {
      savePlot(filename=file, type=type)
    }
  }

  0

} # END: setDevice

# Function to get figs option
getFigs <- function(N) {

  nr <- ceiling(sqrt(N))
  nc <- nr - 1
  if (nr*nc < N) nc <- nr
  ret <- c(nr, nc)
   
  ret

} # END: getFigs

# Function to check limits
getLims <- function(lim) {

  if (is.null(lim)) return(NULL)
  if (length(lim) != 2) stop("ERROR: incorrect axis limits")
  if (lim[1] >= lim[2]) stop("ERROR: incorrect axis limits")
  


} # END: getLims

# Function to create a QQ plot on a -log10 scale.
QQ.plot <- function(pvalues, op=NULL) {

  # pvals      Vector or matrix of p-values
  ###############################################
  # op         List with the optional fields:
  #   title    Title for the plot
  #            The default is "QQ Plot"
  #   ylim     NULL or vector of length 2.
  #            ylim=c(0, 10) will cause the y-axis range to be between
  #            10^{-0} and 10^{-10}
  #            The default is NULL
  #   xlim     NULL or vector of length 2.
  #            xlim=c(0, 10) will cause the x-axis range to be between
  #            10^{-0} and 10^{-10}
  #            The default is NULL
  #   outfile  File to save the plot or NULL.
  #            The default is NULL
  #   type     "jpeg", "ps", or "pdf"
  #            The default is "jpeg"
  #   inflation  List with names tests, squared, etc
  #              The default is NULL
  #   figs     Two-element vecotor for split.screen
  #            The default is NULL
  #   min.p    Minimum p-value. The default is 1e-16
  #   pch      Plot character. The default is 21
  #   cex.lab  Magnification for x and y labels. The default is 1
  #   cex      Magnification of plotting symbol. The default is 1
  #   cex.main For title
  #   cex.axis For axis marks
  #   color    Color of title and p-values
  ###############################################

  op <- default.list(op, c("type", "color", "min.p", "cex.lab", "cex",
                          "pch", "cex.main", "cex.axis"), 
                     list("jpeg", "blue", 1e-16, 1, 1,
                           21, 1, 1))
  op$type <- tolower(op$type)

  pnames <- colnames(pvalues)
  N      <- ncol(pvalues)
  if (is.null(N)) N <- 1
  pvalues <- as.numeric(pvalues)
  pvalues <- matrix(data=pvalues, byrow=FALSE, ncol=N)
  if (is.null(pnames)) pnames <- rep("", N)
  title <- op[["title", exact=TRUE]]
  if (!is.null(title)) pnames[] <- title
  
  if (N > 1) {
    screenFlag  <- 1
    splitScreen <- op[["figs", exact=TRUE]]
    if (is.null(splitScreen)) splitScreen <- getFigs(N)
    split.screen(splitScreen)
  } else {
    screenFlag <- 0
  } 

  min.p <- op$min.p
  if (min.p < 1e-300) min.p <- 1e-300
  xlim  <- op[["xlim", exact=TRUE]]
  ylim  <- op[["ylim", exact=TRUE]]

  # Transform
  MAXP   <- 0
  MAXEXP <- 0 
  for (i in 1:N) {
    vec               <- pvalues[, i]
    miss              <- !is.finite(vec)
    temp              <- vec < min.p
    temp[is.na(temp)] <- FALSE
    vec[temp]         <- min.p
    temp              <- vec > 1
    temp[is.na(temp)] <- FALSE
    vec[temp]         <- 1
    vec[!miss]        <- -log10(vec[!miss])
    vec[miss]         <- NA
    pvalues[, i]      <- vec 
    MAXP              <- max(MAXP, max(vec, na.rm=TRUE))

    n                 <- sum(!miss)
    vec               <- -log10((1:n)/(n+1))
    MAXEXP            <- max(MAXEXP, max(vec, na.rm=TRUE))
  }

  # Get xlim, ylim
  if (is.null(ylim)) ylim <- c(0, ceiling(MAXP))
  if (is.null(xlim)) xlim <- c(0, ceiling(MAXEXP))
  xlabel <- expression(-log[10]("Expected P-values"))
  ylabel <- expression(-log[10]("Observed P-values"))

  maxy <- ceiling(MAXP)
  maxx <- ceiling(MAXEXP)
  m    <- max(maxy, maxx)
  my   <- m
  if (!is.null(ylim)) my <- max(m, ylim)
  ypos <- 0:my
  xpos <- 0:m

  inflation <- op[["inflation", exact=TRUE]]
  infFlag   <- !is.null(inflation)
  if (infFlag) {
    inflation <- default.list(inflation, 
                   c("squared", "y", "cex", "color", "df"), 
                   list(0, 0.5, 2, "red", 1))
    x <- inflation[["x", exact=TRUE]]
    if (is.null(x)) inflation$x <- floor(MAXEXP/2)
  }

  for (i in 1:N) {
    pvals  <- pvalues[, i]

    # Remove non-finite values
    pvals <- pvals[is.finite(pvals)]

    pvals <- sort(pvals, decreasing=TRUE)
    n     <- length(pvals)
    ex    <- -log10((1:n)/(n+1))

    temp <- setDevice(op$outfile, op=list(type=op$type, which=0)) 

    if (screenFlag) screen(i)
    plot(ex, pvals, axes=FALSE, type="p", xlab=xlabel, ylab=ylabel,
          lwd=1, col=op$color[1], ylim=ylim, xlim=xlim, cex.lab=op$cex.lab, cex=op$cex,
          pch=op$pch)

    axis(1, at=xpos, cex.axis=op$cex.axis)
    axis(2, at=ypos, cex.axis=op$cex.axis)
    box()
    title(main=pnames[i], col.main=op$color[1], cex.main=op$cex.main)

    # Add a diagonal line
    abline(a=0, b=1, col="black", lwd=2)

    # for inflation factor
    if (infFlag) {
      tests <- inflation[["tests", exact=TRUE]]
      if (is.null(tests)) {
        tests <- qchisq(1/(10^pvals), df=1, lower.tail=FALSE)
        inflation$squared <- 1
        inflation$df      <- 1
      }    
      infl  <- inflationFactor(tests, squared=inflation$squared, df=inflation$df)
      str   <- paste("Inflation factor = ", round(infl, digits=4), sep="")
      text(x=inflation$x , y=inflation$y, labels=str, cex=inflation$cex, col=inflation$color)
    }

    # See if other p-values need to be plotted
    pvals <- op[["pvalues", exact=TRUE]]
    if (!is.null(pvals)) {
      pvals <- as.numeric(pvals)
      pvals <- sort(pvals)
      n     <- length(pvals)
      ex    <- (1:n)/(n+1)
      pvals[pvals < min.p] <- min.p
      pvals <- -log10(pvals)
      ex    <- -log10(ex)
      points(ex, pvals, type="p", lwd=1, col=op$color[2])
    }
    if (screenFlag) close.screen(i)
  }
  temp <- setDevice(op$outfile, op=list(type=op$type, which=1)) 

  0 

} # END: QQ.plot

# Function to create a QQ plot on a -log10 scale.
QQ.plot_old0 <- function(pvals, op=NULL) {

  # pvals      Vector of p-values
  ###############################################
  # op         List with the optional fields:
  #   title    Title for the plot
  #            The default is "QQ Plot"
  #   ylim     NULL or vector of length 2.
  #            ylim=c(0, 10) will cause the y-axis range to be between
  #            10^{-0} and 10^{-10}
  #            The default is NULL
  #   outfile  File to save the plot or NULL.
  #            The default is NULL
  #   type     "jpeg", "ps", or "pdf"
  #            The default is "jpeg"
  ###############################################

  op <- default.list(op, c("title", "type", "color"), 
                     list("QQ Plot", "jpeg", "blue"))
  op$type <- tolower(op$type)

  pvals <- as.numeric(pvals)

  # Remove non-finite values
  pvals <- pvals[is.finite(pvals)]

  pvals <- sort(pvals)
  n     <- length(pvals)
  ex    <- (1:n)/(n+1)

  # Plot on -log10 scale
  pvals[pvals < 1e-16] <- 1e-16
  pvals <- -log10(pvals)
  ex    <- -log10(ex)

  xlabel <- expression(-log[10]("Expected P-values"))
  ylabel <- expression(-log[10]("Observed P-values"))

  temp <- setDevice(op$outfile, op=list(type=op$type, which=0)) 

  plot(ex, pvals, axes=FALSE, type="p", xlab=xlabel, ylab=ylabel,
        lwd=1, col=op$color[1], ylim=op$ylim)

  maxy <- ceiling(max(pvals))
  maxx <- ceiling(max(ex))
  m    <- max(maxy, maxx)
  my   <- m
  if (!is.null(op$ylim)) my <- max(m, op$ylim)
  ypos <- 0:my
  xpos <- 0:m

  axis(1, at=xpos)
  axis(2, at=ypos)
  box()
  title(main=op$title, col.main="blue", cex.main=1)

  # Add a diagonal line
  abline(a=0, b=1, col="black", lwd=2)

  # See if other p-values need to be plotted
  pvals <- getListName(op, "pvalues")
  if (!is.null(pvals)) {
    pvals <- as.numeric(pvals)
    pvals <- sort(pvals)
    n     <- length(pvals)
    ex    <- (1:n)/(n+1)
    pvals[pvals < 1e-16] <- 1e-16
    pvals <- -log10(pvals)
    ex    <- -log10(ex)
    points(ex, pvals, type="p", lwd=1, col=op$color[2])
  }

  temp <- setDevice(op$outfile, op=list(type=op$type, which=1)) 

  0 

} # END: QQ.plot

# Function to create a QQ plot.
QQ.plot2 <- function(pvals, op=NULL) {

  # pvals      Vector of p-values
  ###############################################
  # op         List with the optional fields:
  #   title    Title for the plot
  #            The default is "QQ Plot"
  #   ylim     NULL or vector of length 2.
  #            ylim=c(0, 10) will cause the y-axis range to be between
  #            10^{-0} and 10^{-10}
  #            The default is NULL
  #   outfile  File to save the plot or NULL.
  #            The default is NULL
  #   type     "jpeg", "ps", or "pdf"
  #            The default is "jpeg"
  ###############################################

  op <- default.list(op, c("title", "type", "color"), 
                     list("QQ Plot", "jpeg", "blue"))
  op$type <- tolower(op$type)

  pvals <- as.numeric(pvals)

  # Remove non-finite values
  pvals <- pvals[is.finite(pvals)]

  pvals <- sort(pvals)
  n     <- length(pvals)
  ex    <- (1:n)/(n)

  # Plot on -log10 scale
  pvals[pvals < 1e-16] <- 1e-16
  pvals <- -2*log(pvals)
  ex    <- qchisq(ex, df=2, lower.tail=FALSE)

  xlabel <- expression("Expected P-values from chi-squared(2) distribution")
  ylabel <- expression("-2log(Observed P-values)")

  temp <- setDevice(op$outfile, op=list(type=op$type, which=0)) 

  plot(ex, pvals, axes=FALSE, type="p", xlab=xlabel, ylab=ylabel,
        lwd=1, col=op$color[1], ylim=op$ylim)

  maxy <- ceiling(max(pvals))
  maxx <- ceiling(max(ex))
  m    <- max(maxy, maxx)
  my   <- m
  if (!is.null(op$ylim)) my <- max(m, op$ylim)
  ypos <- 0:my
  xpos <- 0:m

  axis(1, at=xpos)
  axis(2, at=ypos)
  box()
  title(main=op$title, col.main="blue", cex.main=1)

  # Add a diagonal line
  abline(a=0, b=1, col="black", lwd=2)

  # See if other p-values need to be plotted
  #pvals <- getListName(op, "pvalues")
  #if (!is.null(pvals)) {
  #  pvals <- as.numeric(pvals)
  #  pvals <- sort(pvals)
  #  n     <- length(pvals)
  #  ex    <- (1:n)/(n+1)
  #  pvals[pvals < 1e-16] <- 1e-16
  #  pvals <- -log10(pvals)
  #  ex    <- -log10(ex)
  #  points(ex, pvals, type="p", lwd=1, col=op$color[2])
  #}

  temp <- setDevice(op$outfile, op=list(type=op$type, which=1)) 

  0 

} # END: QQ.plot2

# Function to transform locations for a chromosome plot
transform.loc <- function(chromosome, chrms, map, addToEnd=0) {

  nchrm <- length(chrms)

  # Get the maximum value and length of each chrm
  clen <- rep(NA, times=nchrm)
  cmax <- clen
  for (i in 1:nchrm) {
    temp <- map[(chromosome == chrms[i])]

    # Get the max and min values
    cmax[i] <- max(temp, na.rm=TRUE)
    clen[i] <- cmax[i] - min(temp, na.rm=TRUE) 
  }

  # Remove problem values
  xx <- !is.finite(cmax)
  if (any(xx)) {
    for (i in 1:nchrm) {
      if (xx[i]) {
        temp <- !(chromosome == chrms[i])
        chromosome <- chromosome[temp]
        map        <- map[temp]
      }
    }
    chrms <- chrms[!xx]
  }

  # Scale the lengths
  clen  <- clen/max(clen)
  scale <- clen/cmax 

  # Scale for each chromosome
  chpos <- rep(NA, nchrm)
  add   <- 0
  cmin  <- rep(NA, nchrm)

  for (i in 1:nchrm) {
    temp <- (chromosome == chrms[i])

    # Scale between 0 and 1 and translate
    map[temp] <- scale[i]*map[temp] + add

    # Get min and max
    cmin[i] <- min(map[temp], na.rm=TRUE)
    cmax[i] <- max(map[temp], na.rm=TRUE)

    # Get the new mean
    chpos[i] <- (cmin[i] + cmax[i])/2

    # Update add
    add <- cmax[i] + addToEnd
  }

  list(map=map, chpos=chpos, cmin=cmin, cmax=cmax)

} # END: transform.loc

# Function to create a chromosome plot
Manhattan.plot <- function(infile, plot.vars, locusMap.list, op=NULL) {

  # infile           Input data set containing the p-values.
  #                  infile can be the path to the file or a data
  #                  frame containing the pvalues and the locus map
  #                  variables.
  #                  No default.
  # plot.vars        Variables in infile to plot
  # locusMap.list    List containing info about the file containing, 
  #                  snp, chromosome, and location.
  ###################################################################
  # op               List of options:
  #  splitScreen     0 or 1 to split the plot into 2 parts
  #                  The default is 1.
  #  snp.var         The snp variable name in infile
  #                  The default is "SNP".
  #  yaxis.range     Range for the y-axis. Should be on the original scale.
  #                  Ex: c(1e-12, 1e-3)
  #                  The default is NULL.
  #  title           NULL or title of plot
  #                  The default is NULL
  #  legend          0 or 1 for a legend
  #                  The default is 1
  #  legend.names    The default is plot.vars
  #  legend.horiz    TRUE or FALSE for a horizontal legend
  #                  The default is 1
  #  legend.where    "bottomright", "bottom", "bottomleft", 
  #                         "left", "topleft", "top", "topright", 
  #                         "right" and "center". 
  #                  The default is "top"
  #  cex.axis        X-axis label size
  #                  The default is 0.75
  #  colors          Vector of colors to use
  #                  The default is NULL
  #  alt.colors      0 or 1 to alternate colors in plot
  #                  The default is 1
  #  pch             Vector of plotting symbols
  #                  The default is 21 ("circles")
  #                  19 = solid circle, 20 = bullet
  #  add             A number to add spacing between the chromsomes
  #                  The default is 0.
  #  x.padj          X-axis padj option
  #                  The default depends on x.las
  #  x.las           0-3 for x-axis labels 
  #                  0=parallel, 1=horizontal, 2=perpendicular, 3=vertical
  #                  The default is 2
  #  xlim.add        Vector of length 1 or 2 for adding(subtracting) a 
  #                  value to xlim
  #                  The default is c(0, 0)
  #  xlab            The default is "Chromosome" or "Map Position"
  #  min.p           The minimum p-value. Default is 1e-30
  #  figs            Argument for split.screen. Default is NULL
  #  onePlot         All p-values on 1 plot. The default is 0.
  #  cex
  #  cex.lab
  #  cex.main
  #  tcl             Length of tick marks. Default is -0.5
  #####################################################################
  #  hline           NULL or list specifying a horizontal line
  #    h             y value
  #    lty
  #                  The default is NULL
  #####################################################################

  op      <- default.list(op, 
            c("splitScreen", "snp.var", "legend", "cex.axis", "alt.colors",
              "legend.horiz", "legend.where", "add", "x.las", "xlim.add",
              "min.p", "onePlot", "cex", "cex.lab", "tcl"), 
             list(0, "SNP", 1, 0.75, 1, 
                  "TRUE", "top", 0, 2, c(0, 0),
                  1e-30, 0, 1, 1, -0.5))
  subset  <- op[["subset", exact=TRUE]]
  subFlag <- !is.null(subset)

  plot.vars <- unique(plot.vars)
  nvars     <- length(plot.vars)
  onePlot   <- op$onePlot
  figs      <- op[["figs", exact=TRUE]]
  figsFlag  <- !is.null(figs)
  if ((onePlot) && (figsFlag)) {
    print("NOTE: op$figs is ignored since op$onePlot is 1")
    figsFlag <- 0
  }
  if ((nvars > 1) && (!onePlot)) {
    op$splitScreen <- 0
    if (is.null(figs)) figs <- getFigs(nvars)
    figsFlag <- 1
  }  

  if (nvars == 1) {
    onePlot   <- 1
    op$legend <- 0
  }
  if (figsFlag) op$legend <- 0

  dfFlag  <- is.data.frame(infile) | is.matrix(infile)

  if (!dfFlag) {
    # Check the locusMap list
    locusMap.list <- check.locusMap.list(locusMap.list)

    # Read in the locus map data
    snp  <- NULL
    chrm <- NULL
    map  <- NULL
    for (file in locusMap.list$file) {
      temp <- paste(locusMap.list$dir, file, sep="")
      data <- getLocusMap(temp, locusMap.list)
      snp  <- c(snp, data$snp)
      chrm <- c(chrm, data$chrm)
      map  <- c(map, data$loc)
    }
    rm(data)
    temp <- gc(verbose=FALSE)

  } else {
    infile <- unfactor.all(infile)
    snp    <- infile[, locusMap.list$snp.var]
    chrm   <- as.character(infile[, locusMap.list$chrm.var])
    map    <- as.numeric(infile[, locusMap.list$loc.var])
  }

  if (subFlag) {
    temp <- chrm %in% subset
    chrm <- chrm[temp]
    snp  <- snp[temp]
    map  <- map[temp]
  }

  if (!dfFlag) {
    # Read in the p-values
    tlist <- list(file=infile, file.type=3, header=1, delimiter="\t")
    data  <- getColumns(tlist, c(op$snp.var, plot.vars), temp.list=NULL)

    # Match the snp names
    snp2 <- data[[op$snp.var]]
    data[[op$snp.var]] <- NULL
    rm(tlist)
  } else {
    snp2 <- unfactor(infile[, op$snp.var])
    data <- list()
    for (var in plot.vars) data[[var]] <- as.numeric(infile[, var])
    rm(infile)
    temp <- gc(verbose=FALSE)
  }

  # Get the correct subset for data
  temp  <- snp2 %in% snp
  snp2  <- snp2[temp]
  for (var in plot.vars) {
    data[[var]] <- as.numeric(data[[var]][temp])
  }

  # Match chrm and location to the data
  temp  <- match(snp2, snp)
  if (any(is.na(temp))) stop("ERROR: matching SNP names")
  chrm  <- chrm[temp]
  map   <- map[temp]

  maxp <- rep(NA, times=nvars)
  # Transform p-values to a -log10 scale
  for (i in 1:nvars) { 
    temp <- data[[i]] < op$min.p
    data[[i]][temp] <- op$min.p
    data[[i]]       <- -log10(data[[i]])
    maxp[i]         <- max(data[[i]], na.rm=TRUE)
  } 

  # Remove values
  temp <- (is.finite(map)) & (!is.na(chrm))
  for (i in 1:nvars) temp <- (temp & is.finite(data[[i]]))
  map  <- map[temp]
  chrm <- chrm[temp]
  for (i in 1:nvars) data[[i]] <- data[[i]][temp]

  # y-axis limits
  temp <- op[["yaxis.range", exact=TRUE]]
  ylim <- chrm.plot.ylim(maxp, ylim=temp)

  rm(maxp, var, snp, snp2)
  temp <- gc(verbose=FALSE)
  uchrm <- getUniqueChrm(chrm)
  nchrm <- length(uchrm)

  if (nchrm <= 1) {
    op$splitScreen <- 0
    transLoc       <- 0
  } else {
    transLoc       <- 1
  }

  # axis labels
  xlab <- op[["xlab", exact=TRUE]]
  if (is.null(xlab)) {
    if (nchrm > 1) {
      xlab <- "Chromosome"
    } else {
      xlab <- "Map Position"
    }
  }
  ylab <- expression(-log[10](P-value))

  # Legend
  nclrs <- nvars
  alt.colors <- op$alt.colors
  if (alt.colors) nclrs <- nchrm
  colors <- op[["colors", exact=TRUE]]
  colors <- chrm.plot.colors(nclrs, colors=colors)
  pch    <- chrm.plot.pch(nvars, pch=op[["pch", exact=TRUE]])
  if (op$legend) {
    names <- plot.vars
    temp  <- op[["legend.names", exact=TRUE]]
    if (!is.null(temp)) names <- temp
    legend <- chrm.plot.legend(names, colors, pch, alt.colors,
               horiz=op$legend.horiz, where=op$legend.where)
  } else {
    legend <- NULL
  }

  hline  <- op[["hline", exact=TRUE]]
  x.padj <- op[["x.padj", exact=TRUE]] 

  if (op$splitScreen) {

    half  <- floor(nchrm/2)
    chrm1 <- uchrm[1:half]

    # Get the ids
    temp  <- chrm %in% chrm1
    
    # Top plot
    scr <- split.screen(c(2,1))
    screen(1)

    ret <- chrm.plot.main(data, map, chrm, ids=temp, ylim=ylim[1:2],
           xlab=xlab, ylab=ylab, transLoc=transLoc, legend=legend,
           colors=colors, pch=op$pch, title=op$title, cex.axis=op$cex.axis,
           alt.colors=alt.colors, add=op$add, hline=hline,
           x.las=op$x.las, x.padj=x.padj, xlim.add=op$xlim.add,
           cex=op$cex, cex.main=op$cex.main, cex.lab=op$cex.lab, tcl=op$tcl)
    #close.screen(scr[1])

    # Get the ids for the bottom plot
    temp <- as.logical(1-temp)

    screen(2)
    ret <- chrm.plot.main(data, map, chrm, ids=temp, ylim=ylim[3:4],
            xlab=xlab, ylab=ylab, transLoc=transLoc, legend=legend,
            colors=colors, pch=op$pch, title=op$title, cex.axis=op$cex.axis,
            alt.colors=alt.colors, add=op$add, hline=hline,
            x.las=op$x.las, x.padj=x.padj, xlim.add=op$xlim.add,
            cex=op$cex, cex.main=op$cex.main, cex.lab=op$cex.lab, tcl=op$tcl)
    #close.screen(scr[2])

  } # END: if (splitScreen)
  else {
    if (onePlot) {
      ret <- chrm.plot.main(data, map, chrm, ids=NULL, ylim=ylim[1:2],
              xlab=xlab, ylab=ylab, transLoc=transLoc, legend=legend,
            colors=colors, pch=op$pch, title=op$title, cex.axis=op$cex.axis,
            alt.colors, add=op$add, hline=hline,
            x.las=op$x.las, x.padj=x.padj, xlim.add=op$xlim.add,
            cex=op$cex, cex.main=op$cex.main, cex.lab=op$cex.lab, op$tcl)
    } else {
      pnames <- plot.vars
      title <- op[["title", exact=TRUE]]
      if (!is.null(title)) pnames[] <- title

      split.screen(figs)
      for (i in 1:nvars) {
        screen(i)
        temp <- list()
        temp[[plot.vars[i]]] = data[[i]]
        ret <- chrm.plot.main(temp, map, chrm, ids=NULL, ylim=ylim[1:2],
              xlab=xlab, ylab=ylab, transLoc=transLoc, legend=legend,
            colors=colors, pch=op$pch, title=pnames[i], cex.axis=op$cex.axis,
            alt.colors, add=op$add, hline=hline,
            x.las=op$x.las, x.padj=x.padj, xlim.add=op$xlim.add,
            cex=op$cex, cex.main=op$cex.main, cex.lab=op$cex.lab, tcl=op$tcl)
        close.screen(i)
      }
    }
  }

} # END: chromosome.plot

# Function to produce a plot
chrm.plot.main <- function(pvals, map, chrm, ids=NULL, ylim=c(0, 8),
                  xlab=NULL, ylab=NULL, transLoc=1, legend=NULL,
                  colors=NULL, pch=NULL, title=NULL, cex.axis=0.75,
                  alt.colors=0, add=0, hline=NULL, x.las=0, x.padj=0,
                  xlim.add=c(0,0), cex.main=1, cex=1, cex.lab=1, tcl=-0.5) {

  # pvals   List
 
  if (is.null(ids)) ids <- 1:length(map)
  if (is.null(x.padj)) {
    if (x.las %in% c(0, 1)) {
      x.padj <- -1.0
    } else {
      x.padj <- 0.5
    }
  }

  # Subset the data
  chrm  <- chrm[ids]
  map   <- map[ids]
  vars  <- names(pvals)
  nvars <- length(vars)

  for (i in 1:nvars) pvals[[i]] <- pvals[[i]][ids]

  rm(ids)
  temp <- gc(verbose=FALSE)
  
  uchrms <- getUniqueChrm(chrm)
  nchrms <- length(uchrms)

  if (transLoc) {
    temp   <- transform.loc(chrm, uchrms, map, addToEnd=add)
    map    <- temp$map
    chpos  <- temp$chpos
    cmin   <- temp$cmin
    cmax   <- temp$cmax
  }

  nclrs <- nvars
  if (alt.colors) nclrs <- nchrms

  # Get the colors and plotting characters
  col  <- chrm.plot.colors(nclrs, colors=colors)
  pch  <- chrm.plot.pch(nvars, pch=pch)
  if (length(xlim.add) == 1) xlim.add <- rep(xlim.add, times=2)
  xlim <- c(min(map, na.rm=TRUE)+xlim.add[1], max(map, na.rm=TRUE)+xlim.add[2])

  # Initialize the plot
  if (transLoc) {    
    plot(map[1], pvals[[1]][1], xlab=xlab,ylab=ylab, axes=FALSE, xlim=xlim,
                ylim=ylim, col=col[1], pch=pch[1], cex.lab=cex.lab, cex=cex)
    mxlog <- floor(ylim[2])
    #if (mxlog == 0) mxlog <- maxp[1]
    if (mxlog < 1) {
      axis(2, at=c(ylim[1], mxlog), cex.axis=cex.axis, tcl=tcl)
    } else {
      axis(2, at=floor(ylim[1]:mxlog), cex.axis=cex.axis, tcl=tcl)
    }

    # tcl is for tick mark length
    # padj is for moving the labels close/farther from the axis
    axis(1, at=chpos, labels=uchrms, tcl=tcl, padj=x.padj, las=x.las,
         cex.axis=cex.axis, font=2)
    box()   

  } else {
    plot(map, pvals[[1]], xlab=xlab,ylab=ylab, axes=TRUE, xlim=xlim,
                ylim=ylim, col=col[1], pch=pch[1], cex.lab=cex.lab)
  }

  # Plot the other vars
  if (nvars > 1) {
    for (i in 2:nvars) {
      points(map, pvals[[i]], col=col[i], pch=pch[i], cex=cex)
    }
  }

  # Alternate colors
  if (alt.colors) {
    for (j in 1:nvars) {
      for (i in 1:nchrms) {
        temp <- (chrm == uchrms[i])
        points(map[temp], pvals[[j]][temp], pch=pch[j], col=col[i], cex=cex)
      }
    }
  }

  # Add line segments (tick marks)
  if ((transLoc) & (!alt.colors)) addLineSegments(cmin, cmax, ylim) 

  # Add a legend
  if (!is.null(legend)) {
    legend(x=legend$x, y=legend$y, legend=legend$legend,
           bty=legend$bty, title=legend$title,
           pch=legend$pch, col=legend$col, cex=legend$cex, 
           horiz=legend$horiz)
  }

  # Add title 
  if (!is.null(title)) title(title, cex.main=cex.main)

  if (!is.null(hline)) {
    hline <- default.list(hline, c("h", "lty"), list(7, 2))
    abline(h=hline$h, lty=hline$lty)
  }

} # END: chrm.plot.main

# Function to get the unique chromosomes
getUniqueChrm <- function(chrm) {

  u    <- unique(chrm)
  n    <- as.numeric(u)
  nas  <- is.na(n)
  ch   <- u[nas]
  s    <- sort(n)
  c(s, ch)

} # END: getUniqueChrm

# Function to return a vector of colors
chrm.plot.colors <- function(n, colors=NULL) {

  if (is.null(colors)) {
    col    <- c("blue", "pink", "green", "red", "black", "orange",
                "yellow", "gray", "brown", "turquoise", "gold",
                "violet", "olivedrab", "skyblue", "purple",
                "maroon")
    col <- c(col, col)
    #col <- rainbow(n)
  } else {
    col <- rep(colors, times=n)
  }
  col    <- col[1:n]
  col

} # END: chrm.plot.colors

# Function to return a vector of plotting characters
chrm.plot.pch <- function(n, pch=NULL) {

  if (is.null(pch)) {
    if (n == 1) {
      pch <- 21
    } else {
      pch  <- 0:(n-1)
    }
  } else {
    pch <- rep(pch, times=n)
  }
  pch <- pch[1:n]
  pch

} # END: chrm.plot.pch

# Function to return the legend list
chrm.plot.legend <- function(plot.vars, colors, pch, alt.colors,
                             horiz=TRUE, where="top") {

  nvars  <- length(plot.vars)
  col    <- chrm.plot.colors(nvars, colors=colors)
  if ((alt.colors) && (nvars > 1)) col <- rep("black", times=nvars)
  title  <- NULL
  x      <- where
  y      <- NULL
  legend <- plot.vars
  cex    <- 0.7
  horiz  <- horiz

  list(x=x, y=y, bty="n", pch=pch, col=col, title=title, 
       legend=legend, cex=cex, horiz=horiz)  

} # END: chrm.plot.legend

# Function to add line segments to a graph
addLineSegments <- function(cmin, cmax, ylim) {

  n    <- length(cmin) + 1
  temp <- cmin 
  temp[1] <- cmin[1] - 0.035
  temp[n] <- cmax[n-1] + 0.035
  if (n > 2) {
    for (i in 2:(n-1)) {
      temp[i] <- (cmax[i-1] + cmin[i])/2
    }
  }
  temp0 <- rep.int(-1, times=n)
  temp1 <- rep.int(ylim[1]+0.1, times=n)
  segments(temp, temp0, temp, temp1, lwd=1, font=2)

} # END: addLineSegments

# Function to return the y-axis limits
chrm.plot.ylim <- function(maxp, ylim=NULL) {

  # maxp is on a -log10 scale
  temp <- max(maxp) + 1
  y0   <- c(0, temp, 0, temp)
  if (is.null(ylim)) return(y0)
  n <- length(ylim)
  if (!(n %in% c(2, 4))) return(y0)
  
  for (i in 1:n) {
    if ((ylim[i] > 0) && (ylim[i] <= 1)) ylim[i] <- -log10(ylim[i])
  }

  # check ylim
  if (ylim[1] > ylim[2]) {
    temp    <- ylim[1]
    ylim[1] <- ylim[2]
    ylim[2] <- temp
  }
  if (n == 4) {
    if (ylim[3] > ylim[4]) {
      temp    <- ylim[3]
      ylim[3] <- ylim[4]
      ylim[4] <- temp
    }
  }

  if (n == 2) ylim <- c(ylim, ylim)

  ylim

} # END: chrm.plot.ylim

# Function to return colors
getColors <- function(colVec, op=NULL) {

 # op      List with names
 #  ncolors  (Maximum) number of colors to return
 #           Default is NULL
 #  plot     0 or 1
 #  print    0 or 1
 #  seed     Default is -1
 #  exclude  Character vector of colors to exclude

 op <- default.list(op, c("plot", "print", "seed", "sample"), list(0, 0, -1, 0))

 all <- colors()
 cls <- NULL
 for (cc in colVec) {
   temp <- grep(cc, all, fixed=TRUE)
   if (length(temp)) cls <- c(cls, all[temp])
 }
 
 rm(all)
 gc()
 exclude <- getListName(op, "exclude")
 if (!is.null(exclude)) {
   for (cc in exclude) {
     temp <- grep(cc, cls, fixed=TRUE)
     if (length(temp)) cls <- cls[-temp]
   }
 } 

 seed <- op$seed
 if (seed > 0) set.seed(seed)
 n <- length(cls)
 ncolors <- getListName(op, "ncolors")
 if (!is.null(ncolors)) {
   # If n != ncolors, sample from the colors
   if (n != ncolors) {
     if (n > ncolors) {
       cls <- sample(cls, ncolors, replace=FALSE)
     } else {
       temp <- ncolors - n
       if (temp > n) {
         temp <- sample(cls, temp, replace=TRUE)
       } else {
         temp <- sample(cls, temp, replace=FALSE)
       }
       cls <- c(cls, temp) 
     }
   }
 } else {
   ncolors <- n
 } 

 if (op$sample) cls <- sample(cls, ncolors, replace=FALSE)
 if (op$print) print(cls)
 if (op$plot) pie(rep.int(1, ncolors), col=cls)

 cls

} # END: getColors

# Function to call before plotting
set.plot <- function(op=NULL) {

  winFlag <- (.Platform$OS.type == "windows")
  if (winFlag) return(0)

  op <- default.list(op, c("out", "type", "res"),
           list("ERROR", "jpeg", 100), error=c(1, 0, 0))

  host <- callOS("hostname", intern=TRUE)
  temp <- op[["R_GSCMD", exact=TRUE]]
  if (is.null(temp)) {
    if (host == "biowulf.nih.gov") {
      temp <- "/data/wheelerb/nilanjan/wga/software/ghostscript-8.64/bin/gs" 
    } else {
      temp <- "/data/software/ghostscript-8.64/bin/gs"
    }
  }

  # Set the R_GSCMD environment variable for plots
  Sys.setenv(R_GSCMD=temp)

  bitmap(op$out, type=op$type, res=op$res)

  0 

} # END: set.plot

# Function to call after plotting
save.plot <- function(op=NULL) {

  winFlag <- (.Platform$OS.type == "windows")
  if (!winFlag) {
    #dev.off()
    return(0)
  }

  op <- default.list(op, c("out", "type"),
           list("ERROR", "jpeg"), error=c(1, 0))

  savePlot(filename=op$out, type=op$type)

  0 

} # END: save.plot

# Function for a gene plot
gene.plot <- function(infile, plot.vars, locusMap.list, op=NULL) {

  # infile           Input data set containing the p-values.
  #                  infile can be the path to the file or a data
  #                  frame containing the pvalues and the locus map
  #                  variables.
  #                  No default.
  # plot.vars        Variables in infile to plot
  # locusMap.list    List containing info about the file containing, 
  #                  snp, gene, chromosome, location.
  ###################################################################
  # op               List of options:
  #  splitScreen     0 or 1 to split the plot into 2 parts
  #                  The default is 1.
  #  snp.var         The snp variable name in infile
  #                  The default is "SNP".
  #  yaxis.range     Range for the y-axis. Should be on the original scale.
  #                  Ex: c(1e-12, 1e-3)
  #                  The default is NULL.
  #  title           NULL or title of plot
  #                  The default is NULL
  #  subtitle        NULL or sub-title of plot
  #                  The default is "Gene"
  #  legend          0 or 1 for a legend
  #                  The default is 0
  #  legend.names    The default is plot.vars
  #  legend.horiz    TRUE or FALSE for a horizontal legend
  #                  The default is 1
  #  legend.where    "bottomright", "bottom", "bottomleft", 
  #                         "left", "topleft", "top", "topright", 
  #                         "right" and "center". 
  #                  The default is "top"
  #  cex.axis        X-axis label size
  #                  The default is 0.75
  #  colors          Vector of colors to use
  #                  The default is NULL
  #  pch             Vector of plotting symbols
  #                  The default is 20 ("circles")
  #                  19 = solid circle, 20 = bullet
  #  add             A number to add spacing between the chromsomes
  #                  The default is 0.
  #  x.padj          X-axis padj option
  #                  The default depends on x.las
  #  x.las           0-3 for x-axis labels 
  #                  0=parallel, 1=horizontal, 2=perpendicular, 3=vertical
  #                  The default is 2
  #  xlim.add        Vector of length 1 or 2 for adding(subtracting) a 
  #                  value to xlim
  #                  The default is c(0, 0)
  #  xlab            The default is ""
  #  subset          Character vector of genes to plot
  #                  The default is NULL
  #  chr.text        For the chromosome numbers
  #                  The default is NULL
  #  maxLabelLen     Maximum length of x-axis labels
  #                  The default is NULL
  #  uniform         0 or 1 for uniform spacing of genes in plot
  #                  The default is 1
  #####################################################################
  #  hline           NA or list specifying a horizontal line
  #    h             y value The default is 10e-7
  #    lty
  #                  The default is NULL
  #####################################################################

  op      <- default.list(op, 
            c("splitScreen", "snp.var", "legend", "cex.axis", "alt.colors",
              "legend.horiz", "legend.where", "add", "x.las", "xlim.add", "pch",
              "xlab", "subtitle", "uniform"), 
             list(0, "SNP", 0, 0.75, 1, "TRUE", "top", 0.1, 2, c(0, 0), 20, 
                  "", "Gene", 1))
  subset  <- op[["subset", exact=TRUE]]
  subFlag <- !is.null(subset)

  plot.vars <- unique(plot.vars)
  nvars     <- length(plot.vars)

  dfFlag  <- is.data.frame(infile) | is.matrix(infile)

  locusMap.list <- default.list(locusMap.list, c("gene.var"), list("ERROR"), error=c(1))

  if (!dfFlag) {
    # Check the locusMap list
    locusMap.list <- check.locusMap.list(locusMap.list)

    # Read in the locus map data
    snp  <- NULL
    chrm <- NULL
    map  <- NULL
    gene <- NULL
    for (file in locusMap.list$file) {
      temp <- paste(locusMap.list$dir, file, sep="")
      data <- getLocusMap(temp, locusMap.list)
      snp  <- c(snp, data$snp)
      chrm <- c(chrm, data$chrm)
      map  <- c(map, data$loc)
      gene <- c(gene, data$gene)
    }
    rm(data)
    temp <- gc(verbose=FALSE)

  } else {
    infile <- unfactor.all(infile)
    snp    <- infile[, locusMap.list$snp.var]
    chrm   <- as.character(infile[, locusMap.list$chrm.var])
    map    <- as.numeric(infile[, locusMap.list$loc.var])
    gene   <- infile[, locusMap.list$gene.var]
  }

  if (subFlag) {
    temp <- gene %in% subset
    gene <- gene[temp]
    chrm <- chrm[temp]
    snp  <- snp[temp]
    map  <- map[temp]
  }

  if (!dfFlag) {
    # Read in the p-values
    tlist <- list(file=infile, file.type=3, header=1, delimiter="\t")
    data  <- getColumns(tlist, c(op$snp.var, plot.vars), temp.list=NULL)

    # Match the snp names
    snp2 <- data[[op$snp.var]]
    data[[op$snp.var]] <- NULL
    rm(tlist)
  } else {
    snp2 <- unfactor(infile[, op$snp.var])
    data <- list()
    for (var in plot.vars) data[[var]] <- as.numeric(infile[, var])
    rm(infile)
    temp <- gc(verbose=FALSE)
  }

  # Get the correct subset for data
  temp  <- snp2 %in% snp
  snp2  <- snp2[temp]
  for (var in plot.vars) {
    data[[var]] <- as.numeric(data[[var]][temp])
  }

  # Match chrm and location to the data
  temp  <- match(snp2, snp)
  if (any(is.na(temp))) stop("ERROR: matching SNP names")
  chrm  <- chrm[temp]
  map   <- map[temp]
  gene  <- gene[temp]

  maxp <- rep(NA, times=nvars)
  # Transform p-values to a -log10 scale
  for (i in 1:nvars) { 
    temp <- data[[i]] < 1e-30
    data[[i]][temp] <- 1e-30
    data[[i]]       <- -log10(data[[i]])
    maxp[i]         <- max(data[[i]], na.rm=TRUE)
  } 

  # Remove values
  temp <- (is.finite(map)) & (!is.na(chrm)) & (!is.na(gene))
  for (i in 1:nvars) temp <- (temp & is.finite(data[[i]]))
  map  <- map[temp]
  chrm <- chrm[temp]
  gene <- gene[temp]
  for (i in 1:nvars) data[[i]] <- data[[i]][temp]

  # y-axis limits
  temp <- getListName(op, "yaxis.range")
  ylim <- chrm.plot.ylim(maxp, ylim=temp)

  rm(maxp, var, snp, snp2)
  temp <- gc(verbose=FALSE)
  uchrm <- getUniqueChrm(chrm)

  nchrm <- length(uchrm)
  ngene <- length(unique(gene))

  # Get the genes for each chromosome and order them
  glist <- gene.getOrder(chrm, gene, map)

  if (nchrm <= 1) {
    op$splitScreen <- 0
    transLoc       <- 1
  } else {
    transLoc       <- 1
  }

  # axis labels
  xlab <- op[["xlab", exact=TRUE]]
  if (is.null(xlab)) {
    if (nchrm > 0) {
      xlab <- "Gene"
    } else {
      xlab <- "Map Position"
    }
  }
  xlab <- ""
  ylab <- expression(-log[10](P-value))

  # Legend
  colors <- op[["colors", exact=TRUE]]
  colors <- gene.plot.colors(glist, colors=colors)
  pch    <- chrm.plot.pch(nvars, pch=op$pch)
  if (op$legend) {
    names <- plot.vars
    temp <- getListName(op, "legend.names")
    if (!is.null(temp)) names <- temp
    legend <- chrm.plot.legend(names, colors, pch, NULL,
               horiz=op$legend.horiz, where=op$legend.where)
  } else {
    legend <- NULL
  }

  hline  <- getListName(op, "hline")
  x.padj <- getListName(op, "x.padj") 

  if (op$splitScreen) {

    half  <- floor(nchrm/2)
    chrm1 <- uchrm[1:half]
    chrm2 <- uchrm[(half+1):nchrm]

    # Get the ids
    temp   <- chrm %in% chrm1
    glist1 <- glist[chrm1]
    glist2 <- glist[chrm2]
    
    rm(chrm, chrm1)
    gc()

    # Top plot
    split.screen(c(2,1))
    screen(1)

    ret <- gene.plot.main(data, map, gene, glist1, ids=temp, ylim=ylim[1:2],
           xlab=xlab, ylab=ylab, transLoc=transLoc, legend=legend,
           colors=colors, pch=op$pch, title=op$title, cex.axis=op$cex.axis,
           alt.colors=op$alt.colors, add=op$add, hline=hline,
           x.las=op$x.las, x.padj=x.padj, xlim.add=op$xlim.add,
           maxLabelLen=op$maxLabelLen, subtitle=op$subtitle, chr.text=op$chr.text,
           uniform=op$uniform)

    # Get the ids for the bottom plot
    temp <- as.logical(1-temp)

    screen(2)
    ret <- gene.plot.main(data, map, gene, glist2, ids=temp, ylim=ylim[3:4],
            xlab=xlab, ylab=ylab, transLoc=transLoc, legend=legend,
            colors=colors, pch=op$pch, title=op$title, cex.axis=op$cex.axis,
            alt.colors=op$alt.colors, add=op$add, hline=hline,
            x.las=op$x.las, x.padj=x.padj, xlim.add=op$xlim.add,
            maxLabelLen=op$maxLabelLen, subtitle=op$subtitle, chr.text=op$chr.text,
            uniform=op$uniform)

  } # END: if (splitScreen)
  else {
    rm(chrm)
    gc()

    ret <- gene.plot.main(data, map, gene, glist, ids=NULL, ylim=ylim[1:2],
              xlab=xlab, ylab=ylab, transLoc=transLoc, legend=legend,
            colors=colors, pch=op$pch, title=op$title, cex.axis=op$cex.axis,
            alt.colors=op$alt.colors, add=op$add, hline=hline,
            x.las=op$x.las, x.padj=x.padj, xlim.add=op$xlim.add,
            maxLabelLen=op$maxLabelLen, subtitle=op$subtitle, chr.text=op$chr.text,
            uniform=op$uniform)
  }

} # END: gene.plot

# Function to produce a plot
gene.plot.main <- function(pvals, map, gene, glist, ids=NULL, ylim=c(0, 8),
                  xlab="", ylab=NULL, transLoc=1, legend=NULL,
                  colors=NULL, pch=NULL, title=NULL, cex.axis=0.75,
                  alt.colors=0, add=0, hline=NULL, x.las=0, x.padj=-1.0,
                  xlim.add=c(0,0), maxLabelLen=NULL, subtitle="Gene", chr.text=NULL,
                  uniform=0) {

  # pvals   List
 
  if (is.null(ids)) ids <- 1:length(map)
  if (is.null(x.padj)) {
    if (x.las %in% c(0, 1)) {
      x.padj <- -1.0
    } else {
      x.padj <- 0.5
    }
  }

  # Subset the data
  map   <- map[ids]
  gene  <- gene[ids]
  vars  <- names(pvals)
  nvars <- length(vars)

  for (i in 1:nvars) pvals[[i]] <- pvals[[i]][ids]

  rm(ids)
  temp <- gc(verbose=FALSE)

  nchrms <- length(glist)
  if (transLoc) {
    temp   <- gene.transform.loc(gene, glist, map, addToEnd=add, uniform=uniform)
    map    <- temp$map
    chpos  <- temp$chpos
    cmin   <- temp$cmin
    cmax   <- temp$cmax
    midMap <- temp$midChrMap
  }

  nclrs <- nchrms

  # Get the colors and plotting characters
  col  <- gene.plot.colors(glist, colors=colors)
  pch  <- chrm.plot.pch(nvars, pch=pch)
  if (length(xlim.add) == 1) xlim.add <- rep(xlim.add, times=2)
  xlim <- c(min(map, na.rm=TRUE)+xlim.add[1], max(map, na.rm=TRUE)+xlim.add[2])

  # Initialize the plot
  if (transLoc) {
    
    plot(map[1], pvals[[1]][1], xlab=xlab,ylab=ylab, axes=FALSE, xlim=xlim,
                ylim=ylim, col=col[1], pch=pch[1])
    mxlog <- floor(ylim[2])
    #if (mxlog == 0) mxlog <- maxp[1]
    if (mxlog < 1) {
      axis(2, at=c(ylim[1], mxlog))
    } else {
      axis(2, at=floor(ylim[1]:mxlog))
    }

    # Get the labels (gene names)
    labels <- NULL
    for (i in 1:nchrms) labels <- c(labels, glist[[i]])
    if (!is.null(maxLabelLen)) labels <- substr(labels, 1, maxLabelLen)

    # tcl is for tick mark length
    # padj is for moving the labels close/farther from the axis
    axis(1, at=chpos, labels=labels, tcl=-0.5, padj=x.padj, las=x.las,
         cex.axis=cex.axis, font=2)
    box()   

  } else {
    plot(map, pvals[[1]], xlab=xlab,ylab=ylab, axes=TRUE, xlim=xlim,
                ylim=ylim, col=col[1], pch=pch[1])
  }

  # Plot the other vars
  if (nvars > 1) {
    for (i in 2:nvars) {
      points(map, pvals[[i]], col=col[i], pch=pch[i])
    }
  }

  # Alternate colors
  for (j in 1:nvars) {
    for (i in 1:nchrms) {
      gg  <- glist[[i]]
      ngg <- length(gg)
      for (k in 1:ngg) {
        temp <- (gene == gg[k])
        points(map[temp], pvals[[j]][temp], pch=pch[j], col=col[i])
      }
    }
  }

  # Add line segments (tick marks)
  if ((transLoc) & (!alt.colors)) addLineSegments(cmin, cmax, ylim) 

  # Add a legend
  if (!is.null(legend)) {
    legend(x=legend$x, y=legend$y, legend=legend$legend,
           bty=legend$bty, title=legend$title,
           pch=legend$pch, col=legend$col, cex=legend$cex, 
           horiz=legend$horiz)
  }

  # Add title 
  if (!is.null(title)) title(title, sub=subtitle)

  if (!is.null(hline)) {
    hline <- default.list(hline, c("h", "lty"), list(7, 2))
    abline(h=hline$h, lty=hline$lty)
  }

  # Add Chromosome numbers
  flag <- 1
  if (!is.null(chr.text)) {
    if (!is.list(chr.text)) flag <- 0
  }
  if (flag) {  
    chr.text <- default.list(chr.text, c("cex", "at", "text"), list(0.75, 0, "Chr"))
    mtext(names(glist), side=3, line=0, outer=FALSE, at=midMap, cex=chr.text$cex, font=2)
    mtext(chr.text$text, side=3, line=0, outer=FALSE, at=chr.text$at, cex=chr.text$cex, font=2)
  }

} # END: gene.plot.main

# Function to return a vector of colors
gene.plot.colors <- function(glist, colors=NULL) {

  cls <- colors
  n <- length(glist)
  if (!length(cls)) cls <- NULL
  if (is.null(cls)) {
    cls <- c("blue", "pink", "green", "red", "black", "orange",
                "yellow", "gray", "brown", "turquoise", "gold",
                "violet", "olivedrab", "skyblue", "purple",
                "maroon")
  } 
  lenc <- length(cls)
  if (lenc < n) {
    temp <- ceiling(n/lenc) 
    cls  <- rep(cls, times=temp)
  }
  cls <- cls[1:n]

  cls

} # END: gene.plot.colors

# Function to transform locations for a chromosome plot
gene.transform.loc <- function(gene, glist, map, addToEnd=0, uniform=0) {

  

  nchrm <- length(glist)
  ngene <- length(unique(gene))
  clen <- rep(NA, times=ngene)
  cmax <- clen

  # Get the maximum value and length of each gene
  if (!uniform) {
    ii   <- 1
    for (i in 1:nchrm) {
      gg  <- glist[[i]]
      ngg <- length(gg)
      for (j in 1:ngg) {
        temp <- map[(gene == gg[j])]

        # Get the max and min values
        cmax[ii] <- max(temp, na.rm=TRUE)
        clen[ii] <- cmax[ii] - min(temp, na.rm=TRUE)
        ii       <- ii + 1
      } 
    }
  } else {
    map[]  <- 1
    cmax[] <- 1
    clen[] <- 1
  }

  # Remove problem values
  #xx <- !is.finite(cmax)
  #if (any(xx)) {
  #  for (i in 1:nchrm) {
  #    if (xx[i]) {
  #      temp <- !(chromosome == chrms[i])
  #      chromosome <- chromosome[temp]
  #      map        <- map[temp]
  #    }
  #  }
  #  chrms <- chrms[!xx]
  #}

  # Scale the lengths
  clen  <- clen/max(clen)
  scale <- clen/cmax 

  # Scale for each chromosome
  chpos <- rep(NA, ngene)
  add   <- 0
  cmin  <- rep(NA, ngene)
  midChrMap <- rep(NA, nchrm)

  ii <- 1
  for (i in 1:nchrm) {
    gg   <- glist[[i]]
    ngg  <- length(gg)
    mmin <- 1e100
    mmax <- -999999
    for (j in 1:ngg) {
      temp <- (gene == gg[j])

      # Scale between 0 and 1 and translate
      map[temp] <- scale[ii]*map[temp] + add

      # Get min and max
      cmin[ii] <- min(map[temp], na.rm=TRUE)
      cmax[ii] <- max(map[temp], na.rm=TRUE)

      # Get the new mean
      chpos[ii] <- (cmin[ii] + cmax[ii])/2

      # Update add
      add <- cmax[ii] + addToEnd

      # Get midpoint for chromosome number
      mmin <- min(cmin[ii], mmin)
      mmax <- max(cmax[ii], mmax)

      ii  <- ii + 1
    }
    midChrMap[i] <- (mmin + mmax)/2
  }

  list(map=map, chpos=chpos, cmin=cmin, cmax=cmax, midChrMap=midChrMap)

} # END: gene.transform.loc

# Function to get the genes for each chromosome and order them
gene.getOrder <- function(chrm, gene, map) {

  glist <- list()
  #uchrm <- unique(chrm)
  uchrm <- getUniqueChrm(chrm)
  nchrm <- length(uchrm)
  for (i in 1:nchrm) {
    temp  <- (chrm == uchrm[i])
    gg    <- unique(gene[temp]) 
    ngg   <- length(gg)
    mloc  <- double(ngg)
    # Get the smallest location
    for (j in 1:ngg) {
      temp <- (gene == gg[j]) 
      mloc[j] <- min(map[temp])
    }
    temp <- sort.int(mloc, index.return=TRUE)
    gg <- gg[temp$ix]
    glist[[uchrm[i]]] <- gg
  }

  glist

} # END: gene.getOrder

# Main function for OR plot
OR.plot.main <- function(or, lower=NULL, upper=NULL, op=NULL) {

  # or        Vector or matrix of odds-ratios
  #           A vector is considered as a matrix of dimension c(1, length(or))
  # lower     Vector or matrix of lower confidence limits
  #           The default is NULL
  # upper     Vector or matrix of upper confidence limits
  #           The default is NULL
  # op        List with names
  #  by       1 or 2 for the grouping of ORs
  #           1 = rows, 2 = columns
  #           The default is 1
  #  xlab
  #  ylab
  #  title    Character string or list with names "main" and "sub"
  #  yticks   y-axis tick labels
  #  colors
  #  digits   Number of significant digits on y-axis to round to (if yticks is NULL)
  #           The default is 2
  #  xticks   x-axis tick labels. The default is the names of the or vector/matrix
  #  ylim     Vector of length 1 or 2 to set the y limits
  #           The default is NULL
  #  add      For spacing in plot
  #           The default is either 0 or 0.05 depending on other options
  #  add2     For spacing in plot
  #           The default is 1
  ##################################################################################
  #  legend   List for the legend. Set to NA for no legend.
  #           The default is NULL so that a legend will be created depending on
  #           other options selected and the input or object.
  #################################################################################

  # Function to define the polygon
  definePoly <- function(x0, y0) {

    if ((y0 <= ylim0[2]) && (y0 >= ylim0[1])) {
      x <- c(x0, x0+1, x0+1, x0)
      y <- c(1,     1,   y0, y0)
      return(list(x=x, y=y))
    }
 
    # Define the sawtooth
    x1 <- x0 + 1/3
    x2 <- x0 + 0.5
    x3 <- x0 + 2/3
    x4 <- x0 + 1
    if (y0 > 1) {
      y0 <- ylim0[2] 
      y1 <- y0 - pstep
      y2 <- y0 - pstep/4
      y3 <- y1
      y4 <- y0 - pstep/2
    } else {
      y0 <- ylim0[1] 
      y1 <- y0 + pstep
      y2 <- y0 + pstep/4
      y3 <- y1
      y4 <- y0 + pstep/2
    } 
    x <- c(x0, x1, x2, x3, x4, x4, x0)
    y <- c(y0, y1, y2, y3, y4, 1,  1)

    list(x=x, y=y)
  } # END: definePoly

  lFlag <- !is.null(lower)
  uFlag <- !is.null(upper)
  op    <- default.list(op, c("by", "add2", "digits"), list(1, 1, 2))
  if (is.null(op[["add", exact=TRUE]])) {
    if ((lFlag) || (uFlag)) {
      op$add <- 0.05
    } else {
      op$add <- 0
    }
  }

  legend <- op[["legend", exact=TRUE]]
  if (is.null(legend)) legend <- list()
  temp <- !is.na(legend[1])
  if (!length(temp)) temp <- FALSE
  legendFlag <- temp
  if (legendFlag) {
    legend <- default.list(legend, 
    c("x", "horiz", "cex", "bty", "inset", "y.intersp", "x.intersp"), 
    list("top", TRUE, 1.0, "n", -0.02, 0.75, 1))
  }

  # Set up the matrix of ORs
  d <- dim(or)
  if (is.null(d)) {
    temp <- names(or)
    len     <- length(or)
    dim(or) <- c(1, len)
    colnames(or) <- temp
    if (lFlag) {
      dim(lower) <- c(1, len)
      colnames(lower) <- temp
    }
    if (uFlag) {
      dim(upper) <- c(1, len)
      colnames(upper) <- temp
    }
  }
  if (op$by == 2) {
    or <- t(or)
    if (lFlag) lower <- t(lower)
    if (uFlag) upper <- t(upper)
  }
  d <- dim(or)
  
  temp  <- is.finite(or)
  if (uFlag) temp <- temp & is.finite(upper)
  minor <- min(or[temp], na.rm=TRUE)
  maxor <- max(or[temp], na.rm=TRUE)
  if (lFlag) minor <- min(minor, lower[temp], na.rm=TRUE)
  if (uFlag) maxor <- max(maxor, upper[temp], na.rm=TRUE)
  ymin  <- min(1, minor)
  #h.legend <- (maxor-minor)/25

  ylim  <- op[["ylim", exact=TRUE]]
  ylim0 <- ylim
  if (is.null(ylim)) {
    ylim     <- c(ymin, maxor)
    ylim0    <- ylim
    ylimFlag <- 0
  } else {
    ylimFlag <- 1
  } 
  h.legend <- (ylim[2]-ylim[1])/25 

  # Get the legend position
  if (legendFlag) {
    temp <- legend$x
    if ((!is.null(temp)) && (is.character(temp))) {
      temp <- toupper(substr(temp, 1, 1))
      if (temp == "T") {
        ylim[2] <- ylim[2] + h.legend
      } else if (temp == "B") {
        ylim[2] <- ylim[2] - h.legend
      } 
    }
  }
  pstep <- (ylim[2] - ylim[1])/50

  # Get the x limits
  add  <- op$add
  add2 <- op$add2
  len  <- length(or)
  xmax <- len + len*add + (d[2]-1)*add2
  xlim <- c(0, xmax)  

  ylab <- op[["ylab", exact=TRUE]]
  if (is.null(ylab)) ylab <- "Odds-ratio"
  xlab <- op[["xlab", exact=TRUE]]
  if (is.null(xlab)) xlab <- ""

  plot(1, 1, xlab=xlab,ylab=ylab, axes=FALSE, xlim=xlim,
                ylim=ylim, type="n")
  ylim <- ylim0

  # Get the colors
  col <- op[["colors", exact=TRUE]]
  if (is.null(col)) {
    col <- c("red", "orange", "blue", "green", "purple",
             "brown", "yellow", "pink", "olivedrab", "powderblue", "gray",
             "aquamarine", "magenta", "gold", "darkblue")
  }

  # Use polygon function for each OR
  x0   <- 0
  xavg <- rep(0, times=d[2])
  for (j in 1:d[2]) {
    for (i in 1:d[1]) {
      if (d[1] == 1) {
        a <- x0
        b <- x0 + 1 + add
      } else if (i == 1) {
        a <- x0
      } else if (i == d[1]) {
        b <- x0 + 1
      }

      if (lFlag) {
        temp <- definePoly(x0, lower[i, j])
        x    <- temp$x
        y    <- temp$y
        polygon(x, y, border=col[i], col="white")
      }
      if (uFlag) {
        temp <- definePoly(x0, upper[i, j])
        x    <- temp$x
        y    <- temp$y
        polygon(x, y, border=col[i], col="white")
      }

      val <- or[i, j]
      if (abs(val - 1) >= 0.001) {
        # Define the rectangle
        temp <- definePoly(x0, val)
        x    <- temp$x
        y    <- temp$y
        polygon(x, y, border=NA, col=col[i])
      } else {
        x <- c(x0, x0+1)
        y <- c(1,     1)
        lines(x, y, col=col[i])
      }

      # Update x0
      x0 <- x0 + 1 + add
    }
    # Update x0
    x0 <- x0 + add2
 
    xavg[j] <- (a + b)/2
  }

  # x-axis
  xlabs  <- op[["xticks", exact=TRUE]]
  if (is.null(xlabs)) {
    # Use or matrix names
    xlabs <- colnames(or)
    if (is.null(xlabs)) xlabs <- FALSE
  }

  axis(1, at=xavg, tick=FALSE, labels=xlabs, font=2)

  # y-axis tick marks
  at <- op[["yticks", exact=TRUE]]
  if (is.null(at)) {
    # Determine step size
    if (ylimFlag) {
      min20 <- abs(ylim[1]-1)
      min21 <- abs(ylim[2]-1)
      h     <- max(min20, min21)/4 
      min20 <- ylim[1]
      min21 <- ylim[2]
    } else {
      min20 <- min(abs(minor-1), abs(ylim[1]-1))
      min21 <- min(abs(maxor-1), abs(ylim[2]-1))
      h     <- max(min20, min21)/4 
      min20 <- min(minor, ylim[1])
      min21 <- min(maxor, ylim[2])
    }
    at    <- 1 
    for (i in 1:100) {
      val <- 1 + i*h
      if (val > min21) {
        break
      } else {
        at <- c(at, val)
      }
    }
    for (i in 1:100) {
      val <- 1 - i*h
      if (val < min20) {
        break
      } else {
        at <- c(at, val)
      }
    }
    at <- round(at, digits=op$digits)
  }

  axis(2, at=at, font=2)
  box()

  title <- op[["title", exact=TRUE]]
  if (!is.null(title)) {
    if (is.character(title)) {
      main <- title
      sub  <- NULL
    } else {
      main <- title[["main", exact=TRUE]]
      sub  <- title[["sub", exact=TRUE]]
    }
    title(main=main, sub=sub, font.sub=2)
  }

  # Legend
  if (!legendFlag) return(NULL)

  # Get legend text
  str <- legend[["legend", exact=TRUE]]
  if (is.null(str)) {
    str <- rownames(or)
    if (is.null(str)) return(NULL)  
  }
  legend(x=legend$x, y=NULL, legend=str, bty=legend$bty, title=legend$title, 
           cex=legend$cex, fill=col[1:d[1]], horiz=legend$horiz, border=col[1:d[1]],
           inset=legend$inset, y.intersp=legend$y.intersp, x.intersp=legend$x.intersp)
  
  NULL

} # END: OR.plot.main

# Function to plot ORs from snp.effects object of a particular method
OR.plot.type.method <- function(obj, type, method, op=NULL) {

  # obj    Object of class snp.effects or snp.effects.method
  ##############################################################
  # op
  #  levels1
  #  levels2

  op <- default.list(op, c("addCI"), list(0))
  addCI <- op$addCI

  method <- toupper(method)
  cls <- class(obj)
  if ("snp.effects" %in% cls) {
    obj <- obj[[method, exact=TRUE]]
  } 
  if (is.null(obj)) stop("ERROR in OR.plot.type.method: with obj") 

  # Determine the size of the OR matrix
  temp <- obj[[type, exact=TRUE]]
  or <- temp$effects
  if (addCI) {
    lower <- temp$lower95
    upper <- temp$upper95
  } else {
    lower <- NULL
    upper <- NULL
  }
  if (is.null(or)) stop("ERROR in OR.plot.type.method: with effects")
  var1 <- attr(temp, "var1", exact=TRUE)
  var2 <- attr(temp, "var2", exact=TRUE)
  lev1 <- attr(temp, "levels1", exact=TRUE)
  lev2 <- attr(temp, "levels2", exact=TRUE)

  # Check the levels
  d <- dim(or)
  if (is.null(d)) {
    len     <- length(or)
    dim(or) <- c(1, len)
    d <- dim(or)    
    if (addCI) {
      dim(lower) <- c(1, len)
      dim(upper) <- c(1, len)
    }
  }
  levels1 <- op[["levels1", exact=TRUE]]
  if (is.null(levels1)) levels1 <- lev1
  levels2 <- op[["levels2", exact=TRUE]]
  if (is.null(levels2)) levels2 <- lev2

  rows <- 1:d[1]
  cols <- 1:d[2]

  temp <- lev1 %in% levels1
  if (any(temp)) {
    lev1 <- lev1[temp]
    rows <- rows[temp]
  }
  temp <- lev2 %in% levels2
  if (any(temp)) {
    lev2 <- lev2[temp]
    cols <- cols[temp]
  }
  or <- or[rows, cols]
  if (addCI) {
    lower <- lower[rows, cols]
    upper <- upper[rows, cols]
  }
  if (is.null(dim(or))) {
    len     <- length(or)
    dim(or) <- c(1, len)
    if (addCI) {
      dim(lower) <- c(1, len)
      dim(upper) <- c(1, len)
    }
  }

  # Get the options
  op <- OR.getTitle(2, op, type, var1, var2, levels1=lev1, method=method, levels2=lev2)

  legend <- op[["legend", exact=TRUE]]
  flag   <- 0 
  if (is.null(legend)) {
    if (nrow(or) == 1) {
      legend <- NA
      flag   <- 1
    } else {
      legend <- list(title=var1, legend=lev1)
    }
  }
  if (!flag) legend <- default.list(legend, c("title", "legend"), list(var1, lev1))
  xticks <- lev2

  # Watch out for 1 level2
  if (length(lev2) == 1) {
    legend <- NA
    xticks <- lev1
  }

  op$legend <- legend
  op$xticks <- xticks

  # Call the main function
  OR.plot.main(or, lower=lower, upper=upper, op=op)

  NULL

} # END: OR.plot.type.method

# Function to plot ORs from snp.effects object
OR.plot.type <- function(obj, type, op=NULL) {

  # op
  #  method
  #  levels1    Single level
  #             The default is 1
  #  levels2    Vector of levels or NULL
  #             The default is NULL 

  allMethods <- c("UML", "CML", "EB", "HCL", "CCL", "CLR")
  methods <- op[["method", exact=TRUE]]
  if (is.null(methods)) {
    methods <- allMethods
  } else {
    methods <- toupper(methods)
    temp <- methods %in% allMethods
    methods <- methods[temp]
  }
  if (!length(methods)) stop("Incorrect methods selected")
 
  temp <- methods %in% names(obj)
  methods <- methods[temp]
  n <- length(methods)
  if (!n) stop("ERROR with op$method and/or obj")

  if (n == 1) return(OR.plot.type.method(obj, type, methods, op=op))

  op <- default.list(op, c("levels1", "addCI"), list(1, 0))
  addCI <- op$addCI

  # Determine the size of the OR matrix
  mat <- obj[[1]][[type]]$effects
  if (is.null(mat)) stop("ERROR in OR.plot.type")

  # Get the levels
  levels1 <- op$levels1
  if (length(levels) > 1) stop("ERROR: op$levels1 must be of length 1")
  levels2 <- op[["levels2", exact=TRUE]]

  # Get the matrix of ORs
  for (i in 1:n) {
    temp <- obj[[methods[i]]][[type]]
    eff  <- temp$effects
    if (addCI) {
      l95 <- temp$lower95
      u95 <- temp$upper95
    }
    if (i == 1) {
      var1 <- attr(temp, "var1", exact=TRUE)
      var2 <- attr(temp, "var2", exact=TRUE)
      lev1 <- attr(temp, "levels1", exact=TRUE)
      lev2 <- attr(temp, "levels2", exact=TRUE)
      nlev1 <- length(lev1)
      nlev2 <- length(lev2)
      if (!(levels1 %in% lev1)) stop("ERROR: with op$levels1")
      temp1 <- lev1 == levels1
      cols  <- (1:nlev2)
      if (!is.null(levels2)) {
        temp2 <- lev2 %in% levels2
        if (any(temp2)) {
          lev2 <- lev2[temp2]
          cols <- cols[temp2]
        }
      }
      nc    <- length(lev2)
      or    <- matrix(data=NA, nrow=n, ncol=nc)
      rows  <- (1:nlev1)[temp1]

      if (addCI) {
        lower <- matrix(data=NA, nrow=n, ncol=nc)
        upper <- matrix(data=NA, nrow=n, ncol=nc)
      } else {
        lower <- NULL
        upper <- NULL
      }
    }
    or[i, ] <- eff[rows, cols]
    if (addCI) {
      lower[i, ] <- l95[rows, cols]
      upper[i, ] <- u95[rows, cols]
    } 
  }

  # Get the options
  op <- OR.getTitle(1, op, type, var1, var2, levels1=levels1)

  legend <- op[["legend", exact=TRUE]]
  flag   <- 0 
  if (is.null(legend)) {
    if (nrow(or) == 1) {
      legend <- NA
      flag   <- 1
    } else {
      legend <- list(legend=methods)
    }
  }
  if (!flag) legend <- default.list(legend, c("legend"), list(methods))
  op$legend <- legend
  op$xticks <- lev2

  # Call the main function
  OR.plot.main(or, lower=lower, upper=upper, op=op)


} # END: OR.plot.type

# Function to return the title
OR.getTitle <- function(which, op, type, var1, var2, levels1=NULL, method=NULL, levels2=NULL) {

  n1 <- length(levels1)
  n2 <- length(levels2)
  title <- op[["title", exact=TRUE]]
  if (is.null(title)) title <- list()
  if (is.character(title)) title <- list(main=title)
  mainFlag <- !is.null(title[["main", exact=TRUE]])
  subFlag  <- !is.null(title[["sub", exact=TRUE]])
  if (!mainFlag) {
    allTypes <- c("JointEffects", "StratEffects", "StratEffects.2")
    temp     <- c("Joint Effects", "Stratified Effects", "Stratified Effects")  
    i        <- match(type, allTypes)
    if (which == 1) {
      str   <- paste(temp[i], " of ", var1, "=", levels1, " and ", var2, sep="")
    } else {
      str <- paste(method, " ", temp[i], " of ", var1, sep="")
      if (n1 == 1) str <- paste(str, "=", levels1, sep="")
      str <- paste(str, " and ", var2, sep="")
      if (n2 == 1) str <- paste(str, "=", levels2, sep="")
    }
    title$main <- str
  }
  if (!subFlag) {
    if ((n1 > 1) && (n2 == 1)) {
      title$sub <- var1
    } else {
      title$sub <- var2
    }
  }
  op$title <- title
  
  op

} # END: OR.getTitle 

# Function for an OR plot 
snp.effects.plot <- function(obj.list, op=NULL) {

  # obj.list     Return object from snp.effects or list of return objects from snp.effects
  #              No default
  ########################################################################################
  # NOTE: if obj.list contains more than 1 object, then the options list can
  #       be a list of sublists of the following options.
  # op           List of options
  #  method      Character vector of "UML", "CML", "EB", "HCL", "CCL", "CLR"
  #              The default is NULL
  #  type        One of "JointEffects", "StratEffects", "StratEffects.2"
  #              The default is "StratEffects"
  #  split.screen NULL or 2-element vector to split the plot screen
  #               The default is NULL
  #  levels1
  #  levels2
  #  legend      List with names
  #              The default is NULL
  #  ylim        Numeric vector of length 2 to specify the y limits to be used
  #              for all plots
  #              The default is NULL
  #  addCI       0 or 1 to add 95% confidence intervals to the plot
  #              The default is 0.
  #  title       Character string or list with names "main" and "sub" for the
  #              main and sub titles.
  #              The default is NULL.
 
  
  allMethods <- c("UML", "CML", "EB", "HCL", "CCL", "CLR")
  allTypes   <- c("JointEffects", "StratEffects", "StratEffects.2")

  if (is.null(op)) op <- list(list())
  temp <- c("method", "type", "split.screen", "levels1", "levels2", "ylim", 
            "addCI", "title")
  if (any(names(op) %in% temp)) op <- list(op)
  nop <- length(op)
  for (i in 1:nop) {
    op[[i]] <- default.list(op[[i]], c("type", "method", "addCI"), list("StratEffects", NULL, 0),
            checkList=list(allTypes, allMethods, 0:1))
    type <- op[[i]]$type
    if (length(type) > 1) stop("ERROR: op$type must have length 1")
  }
  
  if (class(obj.list) == "snp.effects") obj.list <- list(obj.list)
  n <- length(obj.list)
  temp <- op[[1]]
  svec <- temp[["split.screen", exact=TRUE]]
  if (is.null(svec)) {
    nrow <- floor(n/2)
    if (!nrow) nrow <- 1
    if (nrow == 1) {
      ncol <- n
    } else {
      for (i in 2:100) {
        if (i*nrow >= n) {
          ncol <- i
          break
        }
      }
    }
    svec <- c(nrow, ncol) 
  }  
  if (length(svec) != 2) stop("ERROR with op$split.screen")
  
  split.screen(svec)
  j <- 1
  for (i in 1:n) {
    screen(i)
    temp <- try(OR.plot.type(obj.list[[i]], op[[j]]$type, op=op[[j]]), silent=TRUE)
    close.screen(i)
    j <- j + 1
    if (j > nop) j <- 1
  }

  invisible(NULL)

} # END: OR.plot

Try the CGEN package in your browser

Any scripts or data that you put into this service are public.

CGEN documentation built on April 28, 2020, 8:08 p.m.