I have the following code:
plot(x = 1, y = 1, xlim = c(1,2), ylim = c(1,2),
ylab = expression(bgroup("(",A[B]^{C},")")[~D[2]] / bgroup("(",E[F]^{G},")")[~H]))
Which leads to this plot:
Is it possible to make the division symbol ("/") taller so it properly divides two expression and doesn't look like it's shooting out of D2?
My attempt at manually drawing it with cex>1 lead to an ugly and fat division symbol. I don't want it fatter, just taller.
I am looking for solutions that use base plot methods.
If you don't mind using latex, you can export the plot using tickz. That will unleash the full power of latex formatting. E.g. with a standard sized division sign it looks like this:
library(devtools)
install_github('daqana/tikzDevice')
library(tikzDevice)
tikz('test.tex', width = 4, height = 3)
par(mar=c(3,6,3,3))
plot(x = 1, y = 1,
xlim = c(1,2), ylim = c(1,2),
ylab = '$(A_B^C)_{D_2} / (E_F^G)_{H}$')
dev.off()
or if you want an even bigger division sign, you can use one of the latex codes (in ascending order of size) \big/, \Big/, \bigg/, or \Bigg/:
tikz('test.tex', width = 4, height = 3)
par(mar=c(3,6,3,3))
plot(x = 1, y = 1,
xlim = c(1,2), ylim = c(1,2),
ylab = '$\\left(A_B^C\\right)_{D_2} \\bigg/ \\left(E_F^G\\right)_{H}$')
dev.off()
Related
I'm having trouble writing a particular expression in R that uses complex subscripts. The expression should look like this: $(A_{1,2,L}, A_{1,2,U})$
I have an expression that produces the correct subscripts (example below) but I'm unable to add the comma between the entries. Do I need to use substitute() or group()?
plot(NULL, xlim = c(0, 2), ylim = c(0,2))
text(x = 1, y = 1, label = expression((A["1,2,L"]~A["1,2,U"])))
Output of example without comma
You need to put the two expressions in a list list(expr1, expr2).
plot(NULL, xlim = c(0, 2), ylim = c(0,2))
text(x = 1, y = 1, label = expression((list(A["1, 2, L"] , A["1, 2, U"]))))
To produce a high-quality png file from a plot, I usually increase the value of the res = argument of the png(). But in the following case, I have a complex 7x4 plotting platform, and changing the res = changes the actual appearance of the plot (e.g., plot frames look much thicker etc.).
I am wondering how I could raise the quality of the following plot while preserving its original appearance (i.e., as shown in the graphical device)?
P.S: I'm just trying to achieve a high-quality version of what I see in my graphical device.
png("Plot.png")
par(mfcol = c(7, 4), mar = rep(.1, 4), oma = rep(7, 4))
invisible(lapply(1:28, plot, t = "n", xaxt = "n", yaxt = "n"))
dev.off()
Does this look better?
png("Plot.png", res = 600, width = 8, height = 7, units = "in")
par(mai = c(0.5,0.5,0.5,0.5))
par(mfcol = c(7, 4), mar = rep(.1, 4), oma = rep(7, 4))
invisible(lapply(1:28, function(x){
plot(rnorm(20), rnorm(20), axes = FALSE, col = sample(1:7, 1), ann = FALSE)
box()
}))
dev.off()
Depending on what you're trying to accomplish, you can also increase width and height parameters within png. As you increase res, if you increase the width and height the relative layout will stay the same, but you'll end up with more pixels so for a given physical dimension it will be higher resolution.
I am sure this is not new for the R community, but is new to me and can't find a clear answer.
Assuming this example:
plot(1:10, xlab="", xaxt="n") # supress OX axis
title(xlab="How can I use cm?", line=2.5)
axis(side=1, at=1:10, line=0.2)
Here I used line argument in function title() to place a label at 2,5 lines of text "outwards from the plot edge" (as described in ?title help). Is there any argument that can take cm, or a way to use cm? Also, how can I find out how many cm does a line of text contains (if there is no other way around)?
Would also be great to know/set the margins in cm and not only like par("mar") [lines of text] or par("mai") [inches]. Is there a way to do that?
Using the line2user function from this answer you can convert centimeters to a "line" then convert the line to user coordinates and add things to the plot using xpd = TRUE:
cm2line <- function(x) {
lh <- par('cin')[2] * par('cex') * par('lheight')
inch <- x/2.54
inch/lh
}
par(mai = rep(5/2.54, 4))
plot.new()
box()
mtext("hello", side = 3, line = cm2line(2))
abline(h = line2user(cm2line(1:5), side = 4), xpd = TRUE)
abline(h = line2user(cm2line(1:5), side = 1), xpd = TRUE)
abline(v = line2user(cm2line(1:5), side = 2), xpd = TRUE)
abline(v = line2user(cm2line(1:5), side = 3), xpd = TRUE)
I'm trying to produce a non-ultrametric tree using the ape package in R and the function plot.phylo(). I'm struggling to find any documentation on how to keep the tip label vertically aligned on their left edge and with a series of dots (variable length) linking the species' name to the tip of the node.
Any help would be much appreciated as well as links to other packages within R that may be able to achieve this.
An example of the newick tree
I don't have any tree examples of what i want, however, the description seems self explanatory. the labels would all be shifted to the very right, and aligned on their left side, then a series of dots (.......) would link the label to where there old position was.
MLJTT = newickTree (as a string)
plot.phylo(read.tree(text = MLJTT), show.tip.label = T,use.edge.length = T, no.margin = T, cex = 0.55)
And example of three that I want to copy the layout of from here:
Ok, I ended up slightly modifying the default plot.phylo code to accomidate such a change. Here's how it looks
library(ape)
plot.phylo2 <- plot.phylo
environment(plot.phylo2) <- environment(plot.phylo)
body(plot.phylo2)[[c(34, 3, 6, 3, 4, 3)]] <- quote({
mx <- max(xx[1:Ntip])
segments(xx[1:Ntip], yy[1:Ntip] + loy, mx, yy[1:Ntip] + loy,
lty=2, col="grey")
text(mx + lox, yy[1:Ntip] + loy, x$tip.label, adj = adj,
font = font, srt = srt, cex = cex, col = tip.color)
})
This is somewhat fragile and may change in different version of ape, I've tested this with version ape_3.1-4. You can check if this will work by verifying that
body(plot.phylo)[[c(34, 3, 6, 3, 4, 3)]]
returns
text(xx[1:Ntip] + lox, yy[1:Ntip] + loy, x$tip.label, adj = adj,
font = font, srt = srt, cex = cex, col = tip.color)
just to make sure we are changing the correct line. But the code above basically replaces that line where the labels are drawn by moving the x axis where they are drawn and adding in the segments for the dotted lines. Then you can run this with your test data
MLJTT = read.tree(text="..<sample data>..")
plot.phylo2(MLJTT,
show.tip.label = T,use.edge.length = T, no.margin = T, cex = 0.55)
And this produces
I think what you may be looking for is the argument to plot.phylo:
align.tip.label = TRUE
Have you tried this?
MLJTT <- rtree(100)
plot.phylo(MLJTT, show.tip.label = T, align.tip.label = T, use.edge.length = T, no.margin = T, cex = 0.55)
I am having problems with aligning my subtitle in chart_Series.
At present it is just writing over the top of the x axis.
Also is it possible to switch off the text that is automatically written at the top of a
chart_Series chart so I can replace it with my own
library(quantmod)
getSymbols("SPY", from="2013-01-01", to=Sys.Date())
chart_Series(SPY)
title("S&P Index", sub = "text1\n\text2\ntext3",
cex.main = 2, font.main= 4, col.main= "blue",
cex.sub = 0.75, font.sub = 3, col.sub = "red")
I would be grateful for your help.
The 'quantmod' graphics are object-oriented. Data is stored in an environment (named 'Env') inside another environment (named whatever you name it, 'cspy' in this case). Special charting functions are stored with along with the data in a 'proto'-object. It is a more object-oriented approach than is used in either the S3 or S4 programming paradigms that are much more common in R. The 'proto'-package should be consulted for more details. After nosing around the code in chartSeries and the object it creates, I can get the labeling at the top to go away with this:
cspy <- chart_Series(SPY, name = NULL)
cspy$Env$actions[[4]] <- NULL
cspy
The 'quantmod' code has this:
cs$Env$name <- name
text.exp <- c(expression(text(1 - 1/3, 0.5, name, font = 2,
col = "#444444", offset = 0, cex = 1.1, pos = 4)),
expression(text(NROW(xdata[xsubset]),
0.5, paste(start(xdata[xsubset]), end(xdata[xsubset]),
sep = " / "), col = 1, adj = c(0, 0), pos = 2)))
cs$add(text.exp, env = cs$Env, expr = TRUE)
... but I wasn't able to figure out a name for that leaf so I looked at :
cspy$Env$actions
... and saw that the name and date-range were in the 4th item. so I just deleted it. (To get rid of only the name it is trivial: chart_Series(SPY, name = NULL). (I don't know if the location of that graphical item in the object will be consistent and I do not see a method for access that object-leaf, so this is possibly an unstable hack.)
To make room for the margin text (subtitle):
png("out.png")
myoma <- par("oma")
myoma[1] <- 3
par("oma" =myoma)
cspy
title("S&P Index", cex.main = 2, font.main= 4, col.main= "blue")
mtext(text= "text1\ntext2\ntext3", side=1, cex = 0.75, font = 3, col = "red",line=7)
dev.off()
I am not familiar with chart_Series plot from before. Normally I would have used the plotting parameter mar to increase the margin at the bottom of the plot, to make some more room for the sub-title. However, I didn't manage to increase the margin that way. Instead I had to use oma, to increase the outer margins of the plot. I added the sub-titles using mtext, instead of using the sub argument in title. You set the distance from the plot with line. The default chart_Series title is turned off by setting name = NULL. Please also note the 'Note' in ?chart_Series: "Highly experimental (read: alpha) use with caution.". Anyway,
par(oma = c(5, 0, 0, 0))
chart_Series(SPY, name = NULL)
title("S&P Index", cex.main = 2, font.main = 4, col.main = "blue")
mtext(text = "text1\n\text2\ntext3",
side = 1, line = 9, cex = 0.75, font = 3, col = "red")