How to edit main title in plot.TukeyHSD? - r

TukeyHSD function prints a title "alpha% family-wise confidence level", which is wrapped inside title function. Therefore, using main = "" approach to remove the title gives an error message:
x <- rnorm(20,5,6)
y <- factor(c(rep("d", 5), rep("i",5), rep("t",5), rep("l",5)))
z <- aov(x ~ y)
plot(TukeyHSD(z), main = "")
Error in plot.default(c(xi[, "lwr"], xi[, "upr"]), rep.int(yvals, 2), :
formal argument "main" matched by multiple actual arguments
Joris Meys suggests placing main = "" into the plot.TukeyHSD function. However, if I try to manually edit the function, I get an error message too:
tukey.edit <- function (x, ...)
{
for (i in seq_along(x)) {
xi <- x[[i]][, -4, drop = FALSE]
yvals <- nrow(xi):1
dev.hold()
on.exit(dev.flush())
plot(c(xi[, "lwr"], xi[, "upr"]), rep.int(yvals, 2),
type = "n", axes = FALSE, xlab = "", ylab = "", main = "", # changed main = NULL to main = ""
...)
axis(1, ...)
axis(2, at = nrow(xi):1, labels = dimnames(xi)[[1L]],
srt = 0, ...)
abline(h = yvals, lty = 1, lwd = 0.5, col = "lightgray")
abline(v = 0, lty = 2, lwd = 0.5, ...)
segments(xi[, "lwr"], yvals, xi[, "upr"], yvals, ...)
segments(as.vector(xi), rep.int(yvals - 0.1, 3), as.vector(xi),
rep.int(yvals + 0.1, 3), ...)
title(xlab = paste("Differences in mean levels of",
names(x)[i])) # removed main from here
box()
}
}
tukey.edit(z)
Error in x[[i]][, -4, drop = FALSE] : incorrect number of dimensions
What did I do wrong and how to remove the title in the plot?

Eh, this is a little bit embarrassing. I did not use TukeyHSD inside the plotting function. This works:
tukey.edit(TukeyHSD(z))

Related

For-loop to dynamically change plot title

I have 5 variables which want to plot and export in one pdf. However, I have some trouble wiht the for-loop I am running,
parC <-list(unit = 100,labelx = "Time",labely = "Time",cols = "black",
pcex = .01, pch = 1,las = 1,
labax = seq(0,nrow(RP),100),
labay = seq(0,nrow(RP),100))
pdf("filename.pdf", onefile=TRUE)
for (i in RP_values){ # the values that are plotted
for (j in name) { # name is a list of names, so that the title changes dynamically
plotting(i, parC, j)
}
}
dev.off()
RP_values = list of values that is plotted
name = list of names to dynamically change the plotting title
plotting = an adjusted version from the plotRP() function of the crqa package. Here I added a main title to the plot.
The code for the plotting() function:
plotting <- function(RP, par, x){
if (exists("par") == FALSE){ # we use some defaults
## default values
unit = 2; labelx = "Time"; labely = "Time"
cols = "black"; pcex = .3; pch = 1; las = 0;
labax = seq(0, nrow(RP), unit); labay = seq(0, nrow(RP), unit);
} else { # we load the values that we desire
for (v in 1:length(par)) assign(names(par)[v], par[[v]])
}
xdim = nrow(RP)
ydim = ncol(RP)
RP = matrix(as.numeric(RP), nrow = xdim, ncol = ydim) # transform it for plotting
ind = which(RP == 1, arr.ind = T)
tstamp = seq(0, xdim, unit)
par(mar = c(5,5, 1, 3), font.axis = 2, cex.axis = 1,
font.lab = 2, cex.lab = 1.2)
plot(tstamp, tstamp, type = "n", xlab = "", ylab = "", xaxt = "n", yaxt = "n", main = x)
matpoints(ind[,1], ind[,2], cex = pcex, col = cols, pch = pch)
mtext(labelx, at = mean(tstamp), side = 1, line = 2.2, cex = 1.2, font = 2)
mtext(labely, at = mean(tstamp), side = 2, line = 2.2, cex = 1.2, font = 2)
# if (is.numeric(labax)){ ## it means there is some default
# mtext(labax, at = seq(1, nrow(RP), nrow(RP)/10), side = 1, line = .5, cex = 1, font = 2)
# mtext(labay, at = seq(1, nrow(RP), nrow(RP)/10), side = 2, line = .5, cex = 1, font = 2)
# } else{
mtext(labax, at = tstamp, side = 1, line = .5, cex = .8, font = 2, las = las)
mtext(labay, at = tstamp, side = 2, line = .5, cex = .8, font = 2, las = las)
# }
}
My problem is instead of 5 plots I get 25, where each plot appears 5 times, but with a different title. If I do not include the "j" part everything works fine, but of course do not have any main title for each plot.
I appreciate any help.
Best,
Johnson
From your description and comments, it appears you need an elementwise loop and not a nested loop. Consider retrieving all pairwise combinations of names and RP_values with expand.grid and iterate through them with mapply. Also, since parC depends on nrows of corresponding RP, have parC defined inside function for only two parameters (with more informative names like title instead of x):
plotting <- function(RP, title) {
parC <- list(unit=100, labelx="Time", labely="Time",
cols="black", pcex=.01, pch=1, las=1,
labax=seq(0, nrow(RP), 100),
labay=seq(0, nrow(RP), 100))
...
plot(tstamp, tstamp, type="n", xlab="", ylab="",
xaxt="n", yaxt="n", main=title)
...
}
params <- expand.grid(RP_values=RP_values, name=name)
out <- mapply(plotting, RP=params$RP_values, title=params$name)

biwavelet package: "cex.axis" not working in plot.biwavelet(); A bug?

I am using biwavelet package to conduct wavelet analysis. However, when I want to adjust the label size for axis using cex.axis, the label size does not changed. On the other hand, cex.lab and cex.main are working well. Is this a bug? The following gives a reproducible example.
library(biwavelet)
t1 <- cbind(1:100, rnorm(100))
t2 <- cbind(1:100, rnorm(100))
# Continuous wavelet transform
wt.t1 <- wt(t1)
par(oma = c(0, 0.5, 0, 0), mar = c(4, 2, 2, 4))
plot(wt.t1,plot.cb = T,plot.phase = T,type = 'power.norm',
xlab = 'Time(year)',ylab = 'Period(year)',mgp=c(2,1,0),
main='Winter station 1',cex.main=0.8,cex.lab=0.8,cex.axis=0.8)
Edit
There was a previous question on this site a month ago: Wavelets plot: changing x-, y- axis, and color plot, but not solved. Any help this time? Thank you!
Yeah, it is a bug. Here is patched version: my.plot.biwavelet()
This version accepts argument cex.axis (defaults to 1), and you can change it when needed. I will briefly explain to you what the problem is, in the "explanation" section in the end.
my.plot.biwavelet <- function (x, ncol = 64, fill.cols = NULL, xlab = "Time", ylab = "Period",
tol = 1, plot.cb = FALSE, plot.phase = FALSE, type = "power.corr.norm",
plot.coi = TRUE, lwd.coi = 1, col.coi = "white", lty.coi = 1,
alpha.coi = 0.5, plot.sig = TRUE, lwd.sig = 4, col.sig = "black",
lty.sig = 1, bw = FALSE, legend.loc = NULL, legend.horiz = FALSE,
arrow.len = min(par()$pin[2]/30, par()$pin[1]/40), arrow.lwd = arrow.len *
0.3, arrow.cutoff = 0.9, arrow.col = "black", xlim = NULL,
ylim = NULL, zlim = NULL, xaxt = "s", yaxt = "s", form = "%Y", cex.axis = 1,
...) {
if (is.null(fill.cols)) {
if (bw) {
fill.cols <- c("black", "white")
}
else {
fill.cols <- c("#00007F", "blue", "#007FFF",
"cyan", "#7FFF7F", "yellow", "#FF7F00", "red",
"#7F0000")
}
}
col.pal <- colorRampPalette(fill.cols)
fill.colors <- col.pal(ncol)
types <- c("power.corr.norm", "power.corr", "power.norm",
"power", "wavelet", "phase")
type <- match.arg(tolower(type), types)
if (type == "power.corr" | type == "power.corr.norm") {
if (x$type == "wtc" | x$type == "xwt") {
x$power <- x$power.corr
x$wave <- x$wave.corr
}
else {
x$power <- x$power.corr
}
}
if (type == "power.norm" | type == "power.corr.norm") {
if (x$type == "xwt") {
zvals <- log2(x$power)/(x$d1.sigma * x$d2.sigma)
if (is.null(zlim)) {
zlim <- range(c(-1, 1) * max(zvals))
}
zvals[zvals < zlim[1]] <- zlim[1]
locs <- pretty(range(zlim), n = 5)
leg.lab <- 2^locs
}
else if (x$type == "wtc" | x$type == "pwtc") {
zvals <- x$rsq
zvals[!is.finite(zvals)] <- NA
if (is.null(zlim)) {
zlim <- range(zvals, na.rm = TRUE)
}
zvals[zvals < zlim[1]] <- zlim[1]
locs <- pretty(range(zlim), n = 5)
leg.lab <- locs
}
else {
zvals <- log2(abs(x$power/x$sigma2))
if (is.null(zlim)) {
zlim <- range(c(-1, 1) * max(zvals))
}
zvals[zvals < zlim[1]] <- zlim[1]
locs <- pretty(range(zlim), n = 5)
leg.lab <- 2^locs
}
}
else if (type == "power" | type == "power.corr") {
zvals <- log2(x$power)
if (is.null(zlim)) {
zlim <- range(c(-1, 1) * max(zvals))
}
zvals[zvals < zlim[1]] <- zlim[1]
locs <- pretty(range(zlim), n = 5)
leg.lab <- 2^locs
}
else if (type == "wavelet") {
zvals <- (Re(x$wave))
if (is.null(zlim)) {
zlim <- range(zvals)
}
locs <- pretty(range(zlim), n = 5)
leg.lab <- locs
}
else if (type == "phase") {
zvals <- x$phase
if (is.null(zlim)) {
zlim <- c(-pi, pi)
}
locs <- pretty(range(zlim), n = 5)
leg.lab <- locs
}
if (is.null(xlim)) {
xlim <- range(x$t)
}
yvals <- log2(x$period)
if (is.null(ylim)) {
ylim <- range(yvals)
}
else {
ylim <- log2(ylim)
}
image(x$t, yvals, t(zvals), zlim = zlim, xlim = xlim,
ylim = rev(ylim), xlab = xlab, ylab = ylab, yaxt = "n",
xaxt = "n", col = fill.colors, ...)
box()
if (class(x$xaxis)[1] == "Date" | class(x$xaxis)[1] ==
"POSIXct") {
if (xaxt != "n") {
xlocs <- pretty(x$t) + 1
axis(side = 1, at = xlocs, labels = format(x$xaxis[xlocs],
form))
}
}
else {
if (xaxt != "n") {
xlocs <- axTicks(1)
axis(side = 1, at = xlocs, cex.axis = cex.axis)
}
}
if (yaxt != "n") {
axis.locs <- axTicks(2)
yticklab <- format(2^axis.locs, dig = 1)
axis(2, at = axis.locs, labels = yticklab, cex.axis = cex.axis)
}
if (plot.coi) {
polygon(x = c(x$t, rev(x$t)), lty = lty.coi, lwd = lwd.coi,
y = c(log2(x$coi), rep(max(log2(x$coi), na.rm = TRUE),
length(x$coi))), col = adjustcolor(col.coi,
alpha.f = alpha.coi), border = col.coi)
}
if (plot.sig & length(x$signif) > 1) {
if (x$type %in% c("wt", "xwt")) {
contour(x$t, yvals, t(x$signif), level = tol,
col = col.sig, lwd = lwd.sig, add = TRUE, drawlabels = FALSE)
}
else {
tmp <- x$rsq/x$signif
contour(x$t, yvals, t(tmp), level = tol, col = col.sig,
lwd = lwd.sig, add = TRUE, drawlabels = FALSE)
}
}
if (plot.phase) {
a <- x$phase
locs.phases <- which(zvals < quantile(zvals, arrow.cutoff))
a[locs.phases] <- NA
phase.plot(x$t, log2(x$period), a, arrow.len = arrow.len,
arrow.lwd = arrow.lwd, arrow.col = arrow.col)
}
box()
if (plot.cb) {
fields::image.plot(x$t, yvals, t(zvals), zlim = zlim, ylim = rev(range(yvals)),
xlab = xlab, ylab = ylab, col = fill.colors,
smallplot = legend.loc, horizontal = legend.horiz,
legend.only = TRUE, axis.args = list(at = locs,
labels = format(leg.lab, dig = 2)), xpd = NA)
}
}
Test
library(biwavelet)
t1 <- cbind(1:100, rnorm(100))
t2 <- cbind(1:100, rnorm(100))
# Continuous wavelet transform
wt.t1 <- wt(t1)
par(oma = c(0, 0.5, 0, 0), mar = c(4, 2, 2, 4))
my.plot.biwavelet(wt.t1,plot.cb = T,plot.phase = T,type = 'power.norm',
xlab = 'Time(year)',ylab = 'Period(year)',mgp=c(2,1,0),
main='Winter station 1',cex.main=0.8,cex.lab=0.8,cex.axis=0.8)
As expected, it is working.
Explanation
In plot.biwavelet(), why passing cex.axis via ... does not work?
plot.biwavelet() generates the your final plot mainly in 3 stages:
image(..., xaxt = "n", yaxt = "n") for generating basic plot;
axis(1, at = atTicks(1)); axis(2, at = atTicks(2)) for adding axis;
fields::image.plot() for displaying colour legend strip.
Now, although this function takes ..., they are only fed to the first image() call, while the following axis(), (including polygon(), contour(), phase.plot()) and image.plot() take none from .... When later calling axis(), no flexible specification with respect to axis control are supported.
I guess during package development time, problem described as in: Giving arguments from “…” argument to right function in R had been encountered. Maybe the author did not realize this potential issue, leaving a bug here. My answer to that post, as well as Roland's comments, points toward a robust fix.
I am not the package author so can not decide how he will fix this. My fix is brutal, but works for you temporary need: just add the cex.axis argument to axis() call. I have reached Tarik (package author) with an email, and I believe he will give you a much better explanation and solution.
I fixed this issue by passing the ... argument to axis in plot.biwavelet. Your code should now work as desired. Note that changes to cex.axis and other axis arguments will affect all three axes (x, y, z).
You can download the new version (0.20.8) of biwavelet from GitHub by issuing the following command at the R console (this assumes that you have the package devtools already installed): devtools::install_github("tgouhier/biwavelet")
Thanks for pointing out the bug!

Changing axes labels for biplot() in R

I am trying to visualize the results of a PCoA{ape} by making a biplot in R.
The axes now get the default labels axis 1 and axis 2, but I want to edit this.
This is the code I have tried:
biplot(pcoa.ntK, Y=NULL, plot.axes=c(1,2), rn=ntnames,
xlabs="PC1 (%)", ylabs="PC2 (%)")
But the labels don't change.
Can someone tell me what I'm doing wrong here?
And I also would like to edit the title, anyone tips for this?
My data:
ntK <- matrix(
c(0.00000, 0.01500, 0.01832, 0.02061, 0.01902, 0.01270, 0.02111, 0.01655, 0.01520, 0.01691,
0.01667, 0.00000, 0.01175, 0.01911, 0.01759, 0.01127, 0.01854, 0.01041, 0.00741, 0.02007,
0.02432, 0.01404, 0.00000, 0.02551, 0.01972, 0.01838, 0.02505, 0.01484, 0.01391, 0.02687,
0.01501, 0.01252, 0.01399, 0.00000, 0.01442, 0.01294, 0.01402, 0.01132, 0.01239, 0.01455,
0.02343, 0.01951, 0.01830, 0.02440, 0.00000, 0.01727, 0.02470, 0.02021, 0.01699, 0.02482,
0.01320, 0.01054, 0.01439, 0.01847, 0.01457, 0.00000, 0.01818, 0.01366, 0.00977, 0.01394,
0.02468, 0.01950, 0.02206, 0.02251, 0.02343, 0.02040, 0.00000, 0.02028, 0.01875, 0.02558,
0.02254, 0.01276, 0.01522, 0.02117, 0.02234, 0.01790, 0.02363, 0.00000, 0.01152, 0.02557,
0.01804, 0.00792, 0.01244, 0.02019, 0.01637, 0.01116, 0.01904, 0.01004, 0.00000, 0.02099,
0.01862, 0.01988, 0.02227, 0.02200, 0.02218, 0.01476, 0.02408, 0.02066, 0.01947, 0.00000),
nrow=10,
ncol=10)
library(ape)
ntnames <- c("A","B","C","D","E","F","G","H","I","J")
pcoa.ntK <- pcoa(ntK)
biplot is a generic function. The default method and the method for use with objects that come from using the prcomp function in the stats package do allow you to specify axis labels and a title, but for some reason the person that wrote the method that is called with objects of class pcoa hasn't allowed you to specify them. I think your only option would be to write your own version of biplot.pcoa (or ask the package maintainer to add this option).
This is a very quick and dirty hack of the function in the ape package that might do what you want, but no promises that it won't have broken something else!
biplot.pcoa <- function (x, Y = NULL, plot.axes = c(1, 2), dir.axis1 = 1, dir.axis2 = 1,
rn = NULL, xlabs = NULL, ylabs = NULL, main = NULL, ...)
{
k <- ncol(x$vectors)
if (k < 2)
stop("There is a single eigenvalue. No plot can be produced.")
if (k < plot.axes[1])
stop("Axis", plot.axes[1], "does not exist.")
if (k < plot.axes[2])
stop("Axis", plot.axes[2], "does not exist.")
if (!is.null(rn))
rownames(x$vectors) <- rn
labels = colnames(x$vectors[, plot.axes])
if (!is.null(xlabs)) labels[1] <- xlabs
if (!is.null(ylabs)) labels[2] <- ylabs
diag.dir <- diag(c(dir.axis1, dir.axis2))
x$vectors[, plot.axes] <- x$vectors[, plot.axes] %*% diag.dir
if (is.null(Y)) {
limits <- apply(x$vectors[, plot.axes], 2, range)
ran.x <- limits[2, 1] - limits[1, 1]
ran.y <- limits[2, 2] - limits[1, 2]
xlim <- c((limits[1, 1] - ran.x/10), (limits[2, 1] +
ran.x/5))
ylim <- c((limits[1, 2] - ran.y/10), (limits[2, 2] +
ran.y/10))
par(mai = c(1, 1, 1, 0.5))
plot(x$vectors[, plot.axes], xlab = labels[1], ylab = labels[2],
xlim = xlim, ylim = ylim, asp = 1)
text(x$vectors[, plot.axes], labels = rownames(x$vectors),
pos = 4, cex = 1, offset = 0.5)
if (is.null(main)){
title(main = "PCoA ordination", line = 2.5)
} else title(main = main, line = 2.5)
}
else {
n <- nrow(Y)
points.stand <- scale(x$vectors[, plot.axes])
S <- cov(Y, points.stand)
U <- S %*% diag((x$values$Eigenvalues[plot.axes]/(n -
1))^(-0.5))
colnames(U) <- colnames(x$vectors[, plot.axes])
par(mai = c(1, 0.5, 1.4, 0))
biplot(x$vectors[, plot.axes], U, xlab = labels[1], ylab = labels[2])
if (is.null(main)) {
title(main = c("PCoA biplot", "Response variables projected",
"as in PCA with scaling 1"), line = 4)
} else title(main = main, line = 4)
}
invisible()
}
biplot(pcoa.ntK, xlabs = 'My x label', ylabs = 'My y label', main = 'My title')
You can check the source code of biplot.pcoa and you'll see it's not that hard to modify. The author of the package decided to hard-code the axis labels based on the input and also the main title of the plot. Here's a modified version that will first check if values for xlab, ylab and main were used before using the pre-defined ones:
biplot.pcoa <- function (x, Y = NULL, plot.axes = c(1, 2), dir.axis1 = 1, dir.axis2 = 1,
rn = NULL, ...)
{
k <- ncol(x$vectors)
if (k < 2)
stop("There is a single eigenvalue. No plot can be produced.")
if (k < plot.axes[1])
stop("Axis", plot.axes[1], "does not exist.")
if (k < plot.axes[2])
stop("Axis", plot.axes[2], "does not exist.")
if (!is.null(rn))
rownames(x$vectors) <- rn
args <- list(...)
labels = ifelse(c("xlab", "ylab") %in% names(args), c(args$xlab, args$ylab), colnames(x$vectors[, plot.axes]))
diag.dir <- diag(c(dir.axis1, dir.axis2))
x$vectors[, plot.axes] <- x$vectors[, plot.axes] %*% diag.dir
if (is.null(Y)) {
limits <- apply(x$vectors[, plot.axes], 2, range)
ran.x <- limits[2, 1] - limits[1, 1]
ran.y <- limits[2, 2] - limits[1, 2]
xlim <- c((limits[1, 1] - ran.x/10), (limits[2, 1] +
ran.x/5))
ylim <- c((limits[1, 2] - ran.y/10), (limits[2, 2] +
ran.y/10))
par(mai = c(1, 1, 1, 0.5))
title <- ifelse("main" %in% names(args), args$main, "PCoA ordination")
plot(x$vectors[, plot.axes], xlab = labels[1], ylab = labels[2],
xlim = xlim, ylim = ylim, asp = 1,
main = title)
text(x$vectors[, plot.axes], labels = rownames(x$vectors),
pos = 4, cex = 1, offset = 0.5)
#title(main = "PCoA ordination", line = 2.5)
}
else {
n <- nrow(Y)
points.stand <- scale(x$vectors[, plot.axes])
S <- cov(Y, points.stand)
U <- S %*% diag((x$values$Eigenvalues[plot.axes]/(n -
1))^(-0.5))
colnames(U) <- colnames(x$vectors[, plot.axes])
par(mai = c(1, 0.5, 1.4, 0))
title <- ifelse("main" %in% names(args), args$main, c("PCoA biplot", "Response variables projected",
"as in PCA with scaling 1"))
biplot(x$vectors[, plot.axes], U, xlab = labels[1], ylab = labels[2], main = title)
# title(main = c("PCoA biplot", "Response variables projected",
# "as in PCA with scaling 1"), line = 4)
}
invisible()
}
Then:
biplot(pcoa.ntK, Y=NULL, plot.axes=c(1,2), rn=ntnames,
xlab="PC1 (%)", main = "Main Title")
Keep in mind this won't change the original function, so you'll need to load this modified version every time you load the package and need wish to set the labels like this.

labeling points on an archetype archmap

How might one add labels to an archmap from the archetypes package? Or alternatively, would it be possible to recreate the archmap output in ggplot?
Using code from the SportsAnalytics demo (I hope this isn't bad form)
library("SportsAnalytics")
library("archetypes")
data("NBAPlayerStatistics0910")
dat <- subset(NBAPlayerStatistics0910,
select = c(Team, Name, Position,
TotalMinutesPlayed, FieldGoalsMade))
mat <- as.matrix(subset(dat, select = c(TotalMinutesPlayed, FieldGoalsMade)))
a3 <- archetypes(mat, 3)
archmap(a3)
I'd like the player names ( NBAPlayerStatistics0910$Name ) over the points on the chart. Something like below but more readable.
If you don't mind tweaking things a bit, you can start with the archmap() function base, toss in an extra parameter and add a text() call:
amap2 <- function (object, a.names, projection = simplex_projection, projection_args = list(),
rotate = 0, cex = 1.5, col = 1, pch = 1, xlab = "", ylab = "",
axes = FALSE, asp = TRUE, ...)
{
stopifnot("archetypes" %in% class(object))
stopifnot(is.function(projection))
k <- object$k
if (k < 3) {
stop("Need at least 3 archetypes.\n")
}
cmds <- do.call(projection, c(list(parameters(object)), projection_args))
if (rotate != 0) {
a <- pi * rotate/180
A <- matrix(c(cos(a), -sin(a), sin(a), cos(a)), ncol = 2)
cmds <- cmds %*% A
}
hmds <- chull(cmds)
active <- 1:k %in% hmds
plot(cmds, type = "n", xlab = xlab, ylab = ylab, axes = axes,
asp = asp, ...)
points(coef(object) %*% cmds, col = col, pch = pch)
######################
# PLAY WITH THIS BIT #
######################
text(coef(object) %*% cmds, a.names, pos=4)
######################
rad <- ceiling(log10(k)) + 1.5
polygon(cmds[hmds, ])
points(cmds[active, ], pch = 21, cex = rad * cex, bg = "grey")
text(cmds[active, ], labels = (1:k)[active], cex = cex)
if (any(!active)) {
points(cmds[!active, , drop = FALSE], pch = 21, cex = rad *
cex, bg = "white", fg = "grey")
text(cmds[!active, , drop = FALSE], labels = (1:k)[!active],
cex = cex, col = "grey20")
}
invisible(cmds)
}
amap2(a3, dat$Name)
Obviously, my completely quick stab is not the end result you're looking for, but it should help you get on your way (if I read what you want to do correctly).

Plotting in a consistent manner across platforms

I decided it was important for R users to be able to play hangman and made an R hangman game. The problem is I don't do many plots for general release and so I don't know how to provide the user with a plot that works independent of platform or gui.
Here's where you can download the complete package that contains large word bank:
library(devtools); install_github("hangman", "trinker")
The function that plots looks like this (I made the word bank go away for reproducibility):
hangman <- function() {
#x1 <- DICTIONARY[sample(1:nrow(DICTIONARY), 1), 1]
x1 <- "trapped"
x <- unlist(strsplit(x1, NULL))
len <- length(x)
x2 <- rep("_", len)
chance <- 0
win1 <- 0
win <- win1/len
wrong <- character()
right <- character()
print(x2, quote = FALSE)
hang.plot <- function(){ #plotting function
plot.new()
mtext("HANGMAN", col = "blue", cex=2)
mtext(paste(x2, collapse = " "), side = 1, cex=1.5)
mtext("wrong", side = 3, cex=1.5,
adj = 0, padj = 5, col = "red")
text(.015, .8, paste(wrong, collapse = "\n"), offset=.3,
cex=1.5, adj=c(0,1))
mtext("correct", side = 3, cex=1.5,
adj = 1, padj = 5, col = "red")
text(.96, .8, paste(right, collapse = "\n"), offset=.3,
cex=1.5, adj=c(0,1))
segments(.365, .77, .365, .83, lwd=2)
segments(.365, .83, .625, .83, lwd=2)
segments(.625, .83, .625, .25, lwd=2)
segments(.57, .25, .675, .25, lwd=2)
parts <- seq_len(length(wrong))
if (identical(wrong, character(0))) {
parts <- 0
}
if (1 %in% parts) {
mtext("O", side = 1, cex=4, adj = .365, padj = -7.2)
mtext("o o", side = 1, cex=1, adj = .3725, padj = -28.2)
mtext("<", side = 1, cex=1, adj = .373, padj = -27.6)
mtext("__", side = 1, cex=1, adj = .373, padj = -27.2)
}
if (2 %in% parts) {
mtext("I", side = 1, cex=4, adj = .375, padj = -6.25)
mtext("I", side = 1, cex=4, adj = .375, padj = -5.5)
mtext("I", side = 1, cex=4, adj = .375, padj = -4.75)
}
if (3 %in% parts) {
segments(.37, .57, .45, .63, lwd=7)
}
if (4 %in% parts) {
segments(.37, .57, .29, .63, lwd=7)
}
if (5 %in% parts) {
segments(.37, .426, .43, .3, lwd=7)
mtext("__", side = 1, cex = 1, adj = .373,
padj = -27.2, col = "white")
mtext("O", side = 1, cex = 1.25, adj = .373, padj = -21.5,
col="red")
}
if (6 %in% parts) {
segments(.37, .426, .31, .3, lwd = 7)
mtext("o o", side = 1, cex = 1, adj = .3725,
padj = -28.2, col="white")
mtext("x x", side = 1, cex=1, adj = .3725, padj = -28.2)
mtext("You Lose", side = 1, cex=8, padj = -3,
col = "darkgreen")
mtext(paste(x2, collapse = " "), side = 1, cex=1.6, col="white")
mtext(paste(x2, collapse = " "), side = 1, cex=1.5, col="white")
mtext(paste(x2, collapse = " "), side = 1, adj = .51, cex=1.6,
col="white")
mtext(paste(x, collapse = " "), side = 1, cex=1.5)
}
if (win1 == len) {
mtext("WINNER!", side = 1, cex=8, padj = -3,
col = "green")
mtext("WINNER!", side = 1, cex=8, adj = .1, padj = -3.1,
col = "darkgreen")
}
} #end of hang.plot
guess <- function(){#start of guess function
cat("\n","Choose a letter:","\n")
y <- scan(n=1,what = character(0),quiet=T)
if (y %in% c(right, wrong)) {
stop(paste0("You've already guessed ", y))
}
if (!y %in% letters) {
stop(paste0(y, " is not a letter"))
}
if (y %in% x) {
right <<- c(right, y)
win1 <<- sum(win1, sum(x %in% y))
win <<- win1/len
message(paste0("Correct!","\n"))
} else {
wrong <<- c(wrong, y)
chance <<- length(wrong)
message(paste0("The word does not contain ", y, "\n"))
}
x2[x %in% right] <<- x[x %in% right]
print(x2, quote = FALSE)
hang.plot()
}#end of guess function
hang.plot()
while(all(win1 != len & chance < 6)){
try(guess())
}
if (win == 1) {
outcome <- "\nCongratulations! You Win!\n"
} else {
outcome <- paste("\nSorry. You loose. The word is:", x1, "\n")
}
cat(outcome)
}
This looks great on RGUI (in windows) where I created it but the plot is misconfigured in RStudio. How can I make the code plot everything in a way that lines up/looks good independent of gui/platform (my friend bryangoodrich suggested grid as a possibility)?
Try to use text() instead of mtext(). All coordinate must be reconsider. Not tested.
To follow on Alan's answer, if you insist on drawing the head as the letter "O", then you'll need to calculate the height of the character, and use text instead of mtext. For example, this works in both rgui and in RStudio (on Windows) to attach the head to the first segment
plot.new()
segments(0.365, 0.77, 0.365, 0.83, lwd = 2)
text(0.365,0.77-strheight("O", cex=4)/2,"O", cex=4)
Resizing doesn't work, but you get the idea.

Resources