Nothing
#' Check color values
#'
#' @description
#' Checks if elements of argument are valid color values
#'
#' @param palette
#' vector with possibly color values (names, RGB, etc.)
#'
mdaplot.areColors <- function(palette) {
sapply(palette, function(x) tryCatch(is.matrix(col2rgb(x)), error = function(e) FALSE))
}
#' Format vector with numeric values
#'
#' @description
#' Format vector with values, so only significant decimal numbers are left.
#'
#' @param data
#' vector or matrix with values
#' @param round.only
#' logical, do formatting or only round the values
#' @param digits
#' how many significant digits take into account
#'
#' @details
#' Function takes into accound difference between values and the values themselves.
#'
#' @return
#' matrix with formatted values
#'
mdaplot.formatValues <- function(data, round.only = FALSE, digits = 3) {
# if values are not numeric - return as is
if (!is.numeric(data[1])) return(data)
fdata <- if (round.only) round(data, digits) else prettyNum(data, digits = digits)
if (!is.null(dim(data))) {
dim(fdata) <- dim(data)
dimnames(fdata) <- dimnames(data)
}
return(fdata)
}
#' Prepare colors based on palette and opacity value
#'
#' @param palette
#' vector with main colors for current pallette
#' @param ncolors
#' number of colors to generate
#' @param opacity
#' opacity for the colors (one value or individual for each color)
#'
#' @return
#' vector with colors
#'
mdaplot.prepareColors <- function(palette, ncolors, opacity) {
# generate colors based on color ramp and palette
colors <- colorRampPalette(palette)(ncolors)
# no opacity - just return colors as is
if (is.null(opacity) || all(opacity == 1)) {
return(colors)
}
# repeate opacity values for each color
if (length(opacity) == 1) {
opacity <- rep(opacity, ncolors)
}
if (length(opacity) != ncolors) {
stop('Wrong number of values for "opacity" parameter!')
}
# apply opacity
for (i in 1:ncolors) {
colors[i] <- adjustcolor(colors[i], alpha.f = opacity[i])
}
return(colors)
}
#' Plot colorbar
#'
#' @description
#' Shows a colorbar if plot has color grouping of elements (points or lines).
#'
#' @param cgroup
#' a vector with values used to make color grouping of the elements
#' @param colmap
#' a colormap to be used for color generation
#' @param lab.col
#' color for legend labels
#' @param lab.cex
#' size for legend labels
#'
mdaplot.showColorbar <- function(cgroup, colmap = "default", lab.col = "darkgray", lab.cex = 0.65) {
# get number of levels for the cgroup
# define if colorbar should be discrete (for factors) or not
shift <- ifelse(is.factor(cgroup), 1, 0)
if (!is.factor(cgroup) && length(unique(cgroup)) > 12) {
# get colors for 8 groups based on colormap
col <- mdaplot.getColors(ngroups = 12, colmap = colmap)
ncol <- length(unique(col))
# split values to intervals
cgroupl <- levels(cut(as.vector(cgroup), ncol))
# get left and right values for the intervals
lvals <- as.numeric(sub("\\((.+),.*", "\\1", cgroupl))
rvals <- as.numeric(sub("[^,]*,([^]]*)\\]", "\\1", cgroupl))
# correct issue with first element
if (min(cgroup) != lvals[1]) {
lvals[1] <- min(cgroup)
}
# combine values and define matrix for labels
vals <- c(lvals, rvals[ncol])
labels <- matrix(0, ncol = 2, nrow = ncol + 1)
} else {
if (!is.factor(cgroup)) {
cgroup <- factor(cgroup)
}
nlevels <- length(attr(cgroup, "levels"))
# no splitting is needed, just use factors as labels
col <- mdaplot.getColors(ngroups = nlevels, colmap = colmap)
ncol <- length(unique(col))
vals <- levels(cgroup)
labels <- matrix(0, ncol = 2, nrow = ncol)
}
# use formatted values as rownames for labels matrix
rownames(labels) <- mdaplot.formatValues(vals)
# get size of the plotting area and calculate size for color bar elements
lim <- par("usr")
dx <- lim[2] - lim[1]
dy <- lim[4] - lim[3]
w <- (dx * 0.8) / ncol
h <- dy * 0.015
shift <- shift * w * 0.02 # 2 percent of segment width
x <- lim[1] + dx * 0.1
y <- lim[4] - (h + 0.1 * h)
# show colorbar and define coordinates for labels
for (i in seq_len(ncol)) {
rect(shift + x + w * (i - 1), y, x + w * i, y - h, col = col[i], border = NA)
labels[i, ] <- c(x + w * (i - 1), y - h)
}
# add last value or shift coordinates if labels shall be centered
if (nrow(labels) > i) {
labels[i + 1, ] <- c(x + w * i, y - h)
} else {
labels[, 1] <- labels[, 1] + w / 2
}
# show labels for colorbar regions
text(labels[, 1], labels[, 2], labels = rownames(labels), pos = 1, col = lab.col, cex = lab.cex)
}
#' Plot lines
#'
#' @description
#' Shows horisontal and vertical lines on a plot.
#'
#' @param point
#' vector with two values: x coordinate for vertical point y for horizontal
#' @param lty
#' line type
#' @param lwd
#' line width
#' @param col
#' color of lines
#'
#' @details
#' If it is needed to show only one line, the other coordinate shall be set to NA.
#'
mdaplot.showLines <- function(point, lty = 2, lwd = 0.75, col = rgb(0.2, 0.2, 0.2)) {
if (!is.na(point[2])) {
abline(h = point[2], lty = lty, lwd = lwd, col = col)
}
if (!is.na(point[1])) {
abline(v = point[1], lty = lty, lwd = lwd, col = col)
}
}
#' Color values for plot elements
#'
#' @description
#' Generate vector with color values for plot objects (lines, points, bars), depending
#' on number of groups for the objects.
#'
#' @param ngroups
#' number of colors to create.
#' @param cgroup
#' vector of values, used for color grouping of plot points or lines.
#' @param colmap
#' which colormap to use ('default', 'gray', 'old', or user defined in form c('col1', 'col2', ...)).
#' @param opacity
#' opacity for colors (between 0 and 1)
#' @param maxsplits
#' if contenuous values are used for color gruping - how many groups to create?
#'
#' @importFrom grDevices col2rgb colorRampPalette rgb adjustcolor
#'
#' @return
#' Returns vector with generated color values
#'
#' @export
mdaplot.getColors <- function(ngroups = NULL, cgroup = NULL, colmap = "default",
opacity = 1, maxsplits = 64) {
# if non of the main arguments defined assume only one color is needed
if (is.null(ngroups) && is.null(cgroup)) {
ngroups <- 1
}
# list with currently supported color maps
colmaps <- list(
"gray" = c(
"#E8E8E8", "#D6D6D6", "#C4C4C4", "#B2B2B2",
"#9A9A9A", "#808080", "#484848", "#101010"
),
# jet (like old in MATLAB)
"jet" = c(
"#00007F", "blue", "#007FFF", "cyan",
"#7FFF7F", "yellow", "#FF7F00", "red", "#7F0000"
),
# old (used in mdatools in versions < 0.10.0)
"old" = c(
"#3288BD", "#66C2A5", "#ABDDA4", "#E6F598",
"#FEE08B", "#FDAE61", "#F46D43", "#D53E4F"
),
# current default
"default" = c(
"#2679B2", "#1C9AA8", "#379531",
"#EED524", "#FB7F28", "#D22C2F"
)
)
# define palette (if colmap has more than one value - take it as palette)
palette <- if (length(colmap) > 1) colmap else colmaps[[colmap]]
if (!all(mdaplot.areColors(palette))) {
stop("Parameter 'colmap' must contains valid color values or name of palette.")
}
# if grayscale palette and only one color is needed reorder pallete so the black is first
if (all(colmap == "gray") && is.null(cgroup) && ngroups == 1) {
palette <- rev(palette)
}
# if cgroup is not provided just return the colors
if (is.null(cgroup)) {
return(mdaplot.prepareColors(palette, ngroups, opacity))
}
if (!is.null(dim(cgroup))) {
stop("Parameter 'cgroup' should be a vector of values or a factor.")
}
# if cgroup is factor return vector with corresponding values
if (is.factor(cgroup)) {
ngroups <- length(attr(cgroup, "levels"))
return(mdaplot.prepareColors(palette, ngroups, opacity)[as.numeric(cgroup)])
}
# if not split it into groups
if (is.null(ngroups)) {
ngroups <- length(unique(cgroup))
ngroups <- ifelse(ngroups > maxsplits, maxsplits, ngroups)
}
# if number of groups is larger make binning of cgroup parameter
if (ngroups > 1) {
cgroup <- cut(as.numeric(cgroup), ngroups, include.lowest = TRUE)
}
# create colors and return
out_palette <- mdaplot.prepareColors(palette, ngroups, opacity)
colors <- out_palette[as.numeric(cgroup)]
attr(colors, "palette") <- out_palette
return(colors)
}
#' Calculate limits for x-axis.
#'
#' @description
#' Calculates limits for x-axis depending on data values that have to be plotted,
#' extra plot elements that have to be shown and margins.
#'
#' @param ps
#' `plotseries` object.
#' @param xlim
#' limits provided by user
#' @param show.labels
#' logical, will data labels be shown on the plot
#' @param show.lines
#' logical or numeric with line coordinates to be shown on the plot.
#' @param show.excluded
#' logical, will excluded values be shown on the plot
#' @param bwd
#' if limits are computed for bar plot, this is a bar width (otherwise NULL)
#'
#' @return
#' Returns a vector with two limits.
#'
mdaplot.getXAxisLim <- function(ps, xlim, show.labels = FALSE, show.lines = FALSE,
show.excluded = FALSE, bwd = 0.8) {
# if user provided limits for x - use them
if (!is.null(xlim)) return(xlim)
# x axis limits in case of bar plot
if (ps$type == "h") {
values <- ps$x_values
bwd <- if (length(values) == 1) 2 * bwd else bwd * min(diff(values))
return(c(min(values) - bwd / 2, max(values) + bwd / 2))
}
# if excluded values must be shown - correct internal limits
xlim <- ps$xlim
# correct if limits are equal
if (diff(xlim) == 0) xlim <- xlim * c(0.95, 1.05)
if (show.excluded && !is.null(ps$x_values_excluded)) {
xlim_excluded <- range(ps$x_values_excluded)
xlim <- c(
min(xlim[1], xlim_excluded[1], na.rm = TRUE),
max(xlim[2], xlim_excluded[2], na.rm = TRUE)
)
}
# if labels must be shown increase the upper limit
if (show.labels) {
xlim[1] <- xlim[1] - diff(xlim) * 0.05
xlim[2] <- xlim[2] + diff(xlim) * 0.05
}
# find if show.lines is in use
if (length(show.lines) == 2 && is.numeric(show.lines[1])) {
xlim <- c(
min(xlim[1], show.lines[1], na.rm = TRUE),
max(xlim[2], show.lines[1], na.rm = TRUE)
)
}
# add extra margins (3.5%)
m <- diff(xlim) * 0.035
xlim <- xlim + c(-m, m)
return(xlim)
}
#' Calculate limits for y-axis.
#'
#' @description
#' Calculates limits for y-axis depending on data values that have to be plotted,
#' extra plot elements that have to be shown and margins.
#'
#' @param ps
#' `plotseries` object.
#' @param ylim
#' limits provided by user
#' @param show.lines
#' logical or numeric with line coordinates to be shown on the plot.
#' @param show.excluded
#' logical, will excluded values be shown on the plot
#' @param show.labels
#' logical, will data labels be shown on the plot
#' @param show.colorbar
#' logical, will colorbar be shown on the plot
#'
#' @return
#' Returns a vector with two limits.
#'
mdaplot.getYAxisLim <- function(ps, ylim, show.lines = FALSE, show.excluded = FALSE,
show.labels = FALSE, show.colorbar = FALSE) {
# if user provided limits for y - use them
if (!is.null(ylim)) return(ylim)
# get computed data limits
ylim <- ps$ylim
# correct if limits are equal
if (diff(ylim) == 0) ylim <- ylim * c(0.95, 1.05)
# if excluded values must be shown - correct internal limits
if (show.excluded && !is.null(ps$y_values_excluded)) {
ylim_excluded <- range(ps$y_values_excluded)
ylim <- c(
min(ylim[1], ylim_excluded[1], na.rm = TRUE),
max(ylim[2], ylim_excluded[2], na.rm = TRUE)
)
}
# if labels must be shown increase the upper limit
if (show.labels) {
ylim[2] <- ylim[2] + diff(ylim) * 0.075
}
# if it is a bar plot and some bars look "down" correct the bottom limit as well
if (show.labels && ps$type == "h" && any(ps$y_values < 0)) {
ylim[1] <- ylim[1] - diff(ylim) * 0.05
}
# find if show.lines is in use
if (length(show.lines) == 2 && is.numeric(show.lines[2])) {
ylim <- c(
min(ylim[1], show.lines[2], na.rm = TRUE),
max(ylim[2], show.lines[2], na.rm = TRUE)
)
}
# add an extra margin to y limit if colorbar must be shown
if (show.colorbar) {
ylim[2] <- ylim[2] + diff(ylim) * 0.20
}
# add extra margins (3.5%)
m <- diff(ylim) * 0.035
ylim <- ylim + c(-m, m)
return(ylim)
}
#' Prepare xticks for plot
#'
#' @param xticks
#' xticks provided by user (if any)
#' @param xlim
#' limits for x axis
#' @param x_values
#' x values for the plot data object
#' @param type
#' type of the plot
#'
#' @export
mdaplot.getXTicks <- function(xticks, xlim, x_values = NULL, type = NULL) {
if (!is.null(xticks)) return(xticks)
if (type != "p" && length(x_values) == 1) return(1)
return(axisTicks(xlim, log = FALSE))
}
#' Prepare yticks for plot
#'
#' @param yticks
#' yticks provided by user (if any)
#' @param ylim
#' limits for y axis
#' @param y_values
#' y values for the plot data object
#' @param type
#' type of the plot
#'
#' @export
mdaplot.getYTicks <- function(yticks, ylim, y_values = NULL, type = NULL) {
if (!is.null(yticks)) return(yticks)
if (type != "p" && length(y_values) == 1) return(1)
return(axisTicks(ylim, log = FALSE))
}
#' Prepare xticklabels for plot
#'
#' @param xticklabels
#' xticklables provided by user (if any)
#' @param xticks
#' xticks (provided or computed)
#' @param excluded_cols
#' columns excluded from plot data (if any)
#'
#' @export
mdaplot.getXTickLabels <- function(xticklabels, xticks, excluded_cols) {
if (is.null(xticklabels)) return(TRUE)
if (is.null(xticks)) stop("You need to specify both 'xticklabels' and 'xticks'")
# if xticklabels were provided - remove excluded columns if any and check the length
if (!is.null(excluded_cols)) xticklabels <- xticklabels[-excluded_cols]
if (length(xticks) != length(xticklabels)) {
stop('Number of elements in "xticks" and "xticklabels" should be the same')
}
return(xticklabels)
}
#' Prepare yticklabels for plot
#'
#' @param yticklabels
#' yticklables provided by user (if any)
#' @param yticks
#' yticks (provided or computed)
#' @param excluded_rows
#' rows excluded from plot data (if any)
#'
#' @export
mdaplot.getYTickLabels <- function(yticklabels, yticks, excluded_rows) {
if (is.null(yticklabels)) return(TRUE)
if (is.null(yticks)) stop("You need to specify both 'yticklabels' and 'yticks'")
# if yticklabels were provided - remove excluded rows if any and check the length
if (length(yticks) != length(yticklabels)) {
stop('Number of elements in "yticks" and "yticklabels" should be the same')
}
return(yticklabels)
}
#' Create axes plane
#'
#' @description
#' Creates an empty axes plane for given parameters
#'
#' @param xticklabels
#' labels for x ticks
#' @param yticklabels
#' labels for y ticks
#' @param xticks
#' values for x ticks
#' @param yticks
#' values for y ticks
#' @param xlim
#' vector with limits for x axis
#' @param ylim
#' vector with limits for y axis
#' @param main
#' main title for the plot
#' @param xlab
#' label for x axis
#' @param ylab
#' label for y axis
#' @param xlas
#' orientation of xticklabels
#' @param ylas
#' orientation of yticklabels
#' @param show.grid
#' logical, show or not axes grid
#' @param grid.lwd
#' line thinckness (width) for the grid
#' @param grid.col
#' line color for the grid
#'
mdaplot.plotAxes <- function(xticklabels = NULL, yticklabels = NULL,
xlim = xlim, ylim = ylim, xticks = NULL, yticks = NULL, main = NULL, xlab = NULL, ylab = NULL,
xlas = 0, ylas = 0, show.grid = TRUE, grid.lwd = 0.5, grid.col = "lightgray") {
# make plot without ticks
plot(0, 0, type = "n", main = main, xlab = xlab, ylab = ylab, xlim = xlim, ylim = ylim,
xaxt = "n", yaxt = "n")
# generate x and y ticks
if (is.null(xticks)) xticks <- axisTicks(xlim, log = FALSE)
if (is.null(yticks)) yticks <- axisTicks(ylim, log = FALSE)
# show x-axis
if (is.null(xticklabels)) xticklabels <- TRUE
axis(1, at = xticks, labels = xticklabels, las = xlas)
# show y-axis
if (is.null(yticklabels)) yticklabels <- TRUE
axis(2, at = yticks, labels = yticklabels, las = ylas)
# show grid if needed
if (show.grid) {
grid(lwd = grid.lwd, col = grid.col)
}
}
#' Plotting function for a single set of objects
#'
#' @description
#' \code{mdaplot} is used to make different kinds of plot for one set of data objects.
#'
#' @param data
#' a vector, matrix or a data.frame with data values.
#' @param ps
#' `plotseries` object, if NULL will be created based on the provided data values
#' @param type
#' type of the plot ("p", "d", "l", "b", "h", "e").
#' @param cgroup
#' a vector with values to use for make color groups.
#' @param colmap
#' a colormap to use for coloring the plot items.
#' @param pch
#' a character for markers (same as \code{plot} parameter).
#' @param col
#' a color for markers or lines (same as \code{plot} parameter).
#' @param bg
#' background color for scatter plots wich `pch=21:25`.
#' @param bwd
#' a width of a bar as a percent of a maximum space available for each bar.
#' @param border
#' color for border of bars (if barplot is used)
#' @param lty
#' line type
#' @param lwd
#' line width
#' @param cex
#' scale factor for the marker
#' @param xlim
#' limits for the x axis (if NULL, will be calculated automatically).
#' @param ylim
#' limits for the y axis (if NULL, will be calculated automatically).
#' @param xlab
#' a title for the x axis (same as \code{plot} parameter).
#' @param ylab
#' a title for the y axis (same as \code{plot} parameter).
#' @param main
#' an overall title for the plot (same as \code{plot} parameter).
#' @param labels
#' a vector with text labels for data points or one of the following: "names", "indices", "values".
#' @param show.labels
#' logical, show or not labels for the data objects.
#' @param show.colorbar
#' logical, show or not colorbar legend if color grouping is on.
#' @param show.lines
#' vector with two coordinates (x, y) to show horizontal and vertical line cross the point.
#' @param show.grid
#' logical, show or not a grid for the plot.
#' @param grid.lwd
#' line thinckness (width) for the grid.
#' @param grid.col
#' line color for the grid.
#' @param show.axes
#' logical, make a normal plot or show only elements (markers, lines, bars) without axes.
#' @param xticks
#' values for x ticks.
#' @param yticks
#' values for y ticks.
#' @param xticklabels
#' labels for x ticks.
#' @param yticklabels
#' labels for y ticks.
#' @param xlas
#' orientation of xticklabels.
#' @param ylas
#' orientation of yticklabels.
#' @param lab.col
#' color for data point labels.
#' @param lab.cex
#' size for data point labels.
#' @param show.excluded
#' logical, show or hide rows marked as excluded (attribute `exclrows`).
#' @param col.excluded
#' color for the excluded objects (rows).
#' @param nbins
#' if scatter density plot is shown, number of segments to split the plot area into.
#' (see also ?smoothScatter)
#' @param force.x.values
#' vector with corrected x-values for a bar plot (do not specify this manually).
#' @param opacity
#' opacity for plot colors (value between 0 and 1).
#' @param pch.colinv
#' allows to swap values for `col` and `bg` for scatter plots with `pch` valyes from 21 to 25.
#' @param ...
#' other plotting arguments.
#'
#' @details
#' Most of the parameters are similar to what are used with standard \code{plot} function. The
#' differences are described below.
#'
#' The function makes a plot of one set of objects. It can be a set of points (scatter plot),
#' bars, lines, scatter-lines, errorbars og an image. The data is organized as a data frame,
#' matrix or vector. For scatter and only first two columns will be used, for bar plot only
#' values from the first row. It is recommended to use \code{\link{mda.subset}} method if plot
#' should be made only for a subset of the data, especially if you have any excluded rows or
#' columns or other special attributed, described in the Bookdown tutorial.
#'
#' If data is a data frame and contains one or more factors, they will be converted to a dummy
#' variables (using function \code{\link{mda.df2mat}}) and appears at the end (last columns) if
#' line or bar plot is selected.
#'
#' The function allows to colorize lines and points according to values of a parameter
#' \code{cgroup}. The parameter must be a vector with the same elements as number of objects (rows)
#' in the data. The values are divided into up to eight intervals and for each interval a
#' particular color from a selected color scheme is assigned. Parameter \code{show.colorbar}
#' allows to turn off and on a color bar legend for this option.
#'
#' The used color scheme is defined by the \code{colmap} parameter. The default scheme is based
#' on color brewer (colorbrewer2.org) diverging scheme with eight colors. There is also a gray
#' scheme (\code{colmap = "gray"}) and user can define its own just by specifing the needed
#' sequence of colors (e.g. \code{colmap = c("red", "yellow", "green")}, two colors is minimum).
#' The scheme will then be generated automatically as a gradient among the colors.
#'
#' Besides that the function allows to change tick values and corresponding tick labels for x and
#' y axis, see Bookdown tutorial for more details.
#'
#' @author
#' Sergey Kucheryavskiy (svkucheryavski@@gmail.com)
#'
#' @seealso
#' \code{\link{mdaplotg}} - to make plots for several sets of data objects (groups of objects).
#'
#' @examples
#' # See all examples in the tutorial.
#'
#' @importFrom grDevices axisTicks dev.cur
#' @importFrom graphics abline axis grid hist image lines matlines par
#' @importFrom graphics plot plot.new points rasterImage rect segments text mtext
#'
#' @export
mdaplot <- function(data = NULL, ps = NULL, type = "p",
pch = 16, col = NULL, bg = par("bg"), bwd = 0.8, border = NA, lty = 1, lwd = 1, cex = 1,
cgroup = NULL, xlim = NULL, ylim = NULL, colmap = "default", labels = NULL,
main = NULL, xlab = NULL, ylab = NULL, show.labels = FALSE,
show.colorbar = !is.null(cgroup), show.lines = FALSE, show.grid = TRUE, grid.lwd = 0.5,
grid.col = "lightgray", show.axes = TRUE, xticks = NULL, yticks = NULL,
xticklabels = NULL, yticklabels = NULL,
xlas = 0, ylas = 0, lab.col = "darkgray", lab.cex = 0.65,
show.excluded = FALSE, col.excluded = "#C0C0C0", nbins = 60,
force.x.values = NA, opacity = 1,
pch.colinv = FALSE, ...) {
if (is.null(ps)) {
# get the data for plot
ps <- plotseries(data, type, col = col, cgroup = cgroup, colmap = colmap, labels = labels,
opacity = opacity)
}
# if cgroup is NULL for plot data - color grouping is not allowed
if (is.null(ps$cgroup)) {
show.colorbar <- FALSE
}
# show axes if needed
if (show.axes) {
# get limits for axes
xlim <- mdaplot.getXAxisLim(ps, xlim = xlim, show.labels = show.labels,
show.excluded = show.excluded, show.lines = show.lines,
bwd = (if (type == "h") bwd else NULL))
ylim <- mdaplot.getYAxisLim(ps, ylim = ylim, show.excluded = show.excluded,
show.lines = show.lines, show.labels = show.labels, show.colorbar = show.colorbar)
# check and prepare xticklabels
xticklabels <- mdaplot.getXTickLabels(xticklabels, xticks, ps$excluded_cols)
xticks <- mdaplot.getXTicks(xticks, xlim, ps$x_values, type)
# check and prepare yticklabels
yticklabels <- mdaplot.getYTickLabels(yticklabels, yticks, ps$excluded_rows)
yticks <- mdaplot.getYTicks(yticks, ylim, ps$y_values, type)
# define title and labels
if (is.null(main)) main <- ps$name
if (is.null(xlab)) xlab <- attr(ps$x_values, "name")
if (is.null(ylab)) ylab <- attr(ps$y_values, "name")
# make an empty plot with proper limits and axis labels
mdaplot.plotAxes(xticklabels = xticklabels, yticklabels = yticklabels, xticks = xticks,
yticks = yticks, xlim = xlim, ylim = ylim, main = main, xlab = xlab, ylab = ylab,
xlas = xlas, ylas = ylas, show.grid = show.grid, grid.lwd = grid.lwd, grid.col = grid.col
)
}
# make plot for the data
switch(type,
"p" = plotScatter(ps, pch.colinv = pch.colinv, pch = pch, bg = bg, lwd = lwd, cex = cex,
col.excluded = col.excluded, show.excluded = show.excluded, ...),
"d" = plotDensity(ps, nbins = nbins, colmap = colmap),
"l" = plotLines(ps, pch = pch, lwd = lwd, lty = lty, cex = cex, show.excluded = show.excluded,
col.excluded = col.excluded, ...),
"b" = plotLines(ps, pch = pch, lwd = lwd, cex = cex, show.excluded = show.excluded,
col.excluded = col.excluded, ...),
"h" = plotBars(ps, bwd = bwd, border = border, force.x.values = force.x.values, ...),
"e" = plotErrorbars(ps, pch = pch, lwd = lwd, cex = cex, ...),
stop("Wrong plot type.")
)
# show lines if needed
if (is.numeric(show.lines) && length(show.lines) == 2) {
mdaplot.showLines(show.lines)
}
# show lables
if (show.labels) {
showLabels(ps, show.excluded = show.excluded, col = lab.col, cex = lab.cex,
force.x.values = force.x.values, bwd = bwd)
}
# show colorbar if needed
if (show.colorbar) {
mdaplot.showColorbar(ps$cgroup, ps$colmap, lab.col = lab.col, lab.cex = lab.cex)
}
invisible(ps)
}
#' Create line plot with double y-axis
#'
#' @description
#' \code{mdaplotyy} create line plot for two plot series and uses separate y-axis for each.
#'
#' @param data
#' a matrix or a data.frame with two rows of values.
#' @param type
#' type of the plot ("l" or "b").
#' @param col
#' a color for markers or lines (same as \code{plot} parameter) for each series.
#' @param lty
#' line type for each series (two values)
#' @param lwd
#' line width for each series (two values)
#' @param pch
#' a character for markers (same as \code{plot} parameter) for each series (two values).
#' @param cex
#' scale factor for the markers
#' @param xlim
#' limits for the x axis (if NULL, will be calculated automatically).
#' @param ylim
#' limits for the y axis, either list with two vectors (one for each series) or NULL.
#' @param main
#' an overall title for the plot (same as \code{plot} parameter).
#' @param xlab
#' a title for the x axis (same as \code{plot} parameter).
#' @param ylab
#' a title for each of the two y axis (as a vector of two text values).
#' @param labels
#' a vector with text labels for data points or one of the following: "names", "indices", "values".
#' @param show.labels
#' logical, show or not labels for the data objects.
#' @param lab.cex
#' size for data point labels.
#' @param lab.col
#' color for data point labels.
#' @param show.grid
#' logical, show or not a grid for the plot.
#' @param grid.lwd
#' line thinckness (width) for the grid.
#' @param grid.col
#' line color for the grid.
#' @param xticks
#' values for x ticks.
#' @param xticklabels
#' labels for x ticks.
#' @param xlas
#' orientation of xticklabels.
#' @param ylas
#' orientation of yticklabels (will be applied to both y axes).
#' @param show.legend
#' logical show legend with name of each plot series or not
#' @param legend.position
#' position of legend if it must be shown
#' @param legend
#' values for the legend
#' @param ...
#' other plotting arguments.
#'
#' @details
#' This plot has properties both \code{mdaplot} and \code{mdaplotg}, so when you specify color,
#' line properties etc. you have to do it for both plot series.
#'
#' @author
#' Sergey Kucheryavskiy (svkucheryavski@@gmail.com)
#'
#' @seealso
#' \code{\link{mdaplotg}} - to make plots for several sets of data objects (groups of objects).
#'
#' @examples
#' # See all examples in the tutorial.
#'
#' @export
mdaplotyy <- function(data, type = "l", col = mdaplot.getColors(2), lty = c(1, 1),
lwd = c(1, 1), pch = (if (type == "b") c(16, 16) else c(NA, NA)), cex = 1,
xlim = NULL, ylim = NULL, main = attr(data, "name"), xlab = attr(data, "xaxis.name"),
ylab = rownames(data), labels = "values", show.labels = FALSE, lab.cex = 0.65,
lab.col = "darkgray", show.grid = TRUE, grid.lwd = 0.5, grid.col = "lightgray",
xticks = NULL, xticklabels = NULL, xlas = 0, ylas = 0, show.legend = TRUE,
legend.position = "topright", legend = ylab, ...) {
if (!(type %in% c("l", "b"))) {
stop("YY line plot can only be made for type 'l' or 'b'.")
}
if (nrow(data) != 2) {
stop("Matrix with two rows is required to make YY line plot.")
}
if (length(ylab) != 2) {
stop("Y-axis label ('ylab') should be specified for both axes.")
}
if (length(col) != 2 || length(lty) != 2 || length(lwd) != 2 || length(pch) != 2) {
stop("Color and line properties should be specified for both series.")
}
# create plot series
ps1 <- plotseries(mda.subset(data, subset = 1), type = type, labels = labels, col = col[1])
ps2 <- plotseries(mda.subset(data, subset = 2), type = type, labels = labels, col = col[2])
# get limits for first series
xlim <- mdaplot.getXAxisLim(ps1, xlim = xlim, show.labels = show.labels)
ylim1 <- mdaplot.getYAxisLim(ps1, ylim = ylim[[1]], show.labels = show.labels,
show.colorbar = TRUE)
# check and prepare xticklabels
xticklabels <- mdaplot.getXTickLabels(xticklabels, xticks, NULL)
xticks <- mdaplot.getXTicks(xticks, xlim, ps1$x_values, type)
# check and prepare yticklabels
yticklabels <- mdaplot.getYTickLabels(NULL, NULL, NULL)
yticks <- mdaplot.getYTicks(NULL, ylim1, ps1$y_values, type)
# define title and labels
if (is.null(main)) main <- ps1$name
par(mar = c(5, 5, 5, 5))
# make an empty plot with proper limits and axis labels
mdaplot.plotAxes(xticklabels = xticklabels, yticklabels = yticklabels, xticks = xticks,
yticks = yticks, xlim = xlim, ylim = ylim1, main = main, xlab = xlab, ylab = ylab[1],
xlas = xlas, ylas = ylas, show.grid = show.grid, grid.lwd = grid.lwd, grid.col = grid.col
)
# show first series
plotLines(ps1, col = col[1], lty = lty[1], lwd = lwd[1], cex = cex, pch = pch[1], ...)
if (show.labels) {
showLabels(ps1, show.excluded = FALSE, col = lab.col, cex = lab.cex)
}
# second series
ylim2 <- mdaplot.getYAxisLim(ps2, ylim = ylim[[2]], show.labels = show.labels)
par(new = TRUE)
plot(ps2$x_values, ps2$y_values[1, ], type = type, col = col[2], axes = FALSE, xlab = NA,
xlim = xlim, ylab = NA, ylim = ylim2, lty = lty[2], lwd = lwd[2], cex = cex, pch = pch[2],
...)
axis(side = 4, las = ylas)
mtext(side = 4, line = 2, ylab[2], cex = 0.9)
if (show.labels) {
showLabels(ps2, show.excluded = FALSE, col = lab.col, cex = lab.cex)
}
if (show.legend) {
mdaplotg.showLegend(legend, col = col, pch = pch, lty = lty, lwd = lwd, cex = 0.9,
position = legend.position)
}
par(mar = c(5.1, 4.1, 4.1, 2.1))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.