I struggle to fix text in my plot using mtext
Assuming this is my data:
df<-rnorm(100,12,2)
The codes used are :
plot(df)
mtext(col="red",side=3,line=1,at=39, paste(round(12,4)))
mtext('text here=',col="dark green", side=3, line=1, at=10)
When I use these codes, I get a gap between 'text here=' and the value of '12'. When I fix it, and when I expand the plot area in Rstudio, I will get the gap.
I want to have text here= 12 and when I expand the plot, it is not going to be changed.
It would be good if we could simplify the codes.
You could use a phantom expression with bquote for that:
Edit:
To adjust the position, use adj and padj.
df<-rnorm(100,12,2)
plot(df)
txt1 <- bquote(expression("text here = " * phantom(.(round(12,4)))))
txt2 <- bquote(expression(phantom("text here = ") * .(round(12,4))))
mtext(eval(txt1), col = "dark green", adj=0, padj=-1)
mtext(eval(txt2), col = "red", adj=0, padj=-1)
Created on 2020-03-28 by the reprex package (v0.3.0)
My answer will look as a hack because it is a hack:
plot(df)
mtext(col=c("red","blue"), side=3, line=1, at=10,
c('text here = ', paste0(c(rep(" ", 23), 12), collapse = "")))
You will have to find how many spaces you have to use (here is 23) before the number you want to appear (12). Resizing the plot did not change the relative positions between the text and number.
Of course, this will be difficult to adapt if the text varies from graph to graph.
I hope someone else comes with a better answer.
Great answer by #user12728748 !
Related
I have a following problem.
I want to put a legend into my graph. My code:
plot(Lc(`BEL_2016_final.csv`$value),col="red",lwd=2,
xaxt="n", yaxt="n", cex.lab = 1.5)
axis(side=1, at=axTicks(1), cex.axis = 1.5)
axis(side=2, at=axTicks(2), cex.axis = 1.5)
par(new=TRUE)
plot(Lc(`CRO_2016_final.csv`$value),col="blue",lwd=2,
xaxt="n", yaxt="n", cex.lab = 1.5)
axis(side=1, at=axTicks(1), cex.axis = 1.5)
axis(side=2, at=axTicks(2), cex.axis = 1.5)
legend(x = "topleft", legend=paste0(c("Belgium, Gini "),
round(Gini(`BEL_2016_final.csv`$value), digits = 2),
c("Croatia, Gini "),
round(Gini(`CRO_2016_final.csv`$value), digits = 2)),
col=c("red", "blue"), lty=1:2, cex=1, lwd=1.5)
However, the legend looks like this:
When I try:
legend=paste0(c("Belgium, Gini ", "Croatia, Gini "),
round(c(Gini(`BEL_2016_final.csv`$value)),
Gini(`CRO_2016_final.csv`$value)),
digits = 2)
I got this result:
which is wrong, because Gini index for Croatia is 0.73.
How can I modify my code to display both lines (red and blue) in the legend, both on a new line? Thanks a lot.
Your parentheses are mismatched. Whatever IDE/editor you are using I encourage the use of matching (sometimes "rainbow") parentheses. For example, in RStudio, if the cursor is the _ symbol (and accepting RStudio's insistence on its indentation preference):
notice that the ( next to paste0 is highlighted, suggesting you that digits=2 is the last argument in paste0. This is incorrect. Another hint is using RStudio's indentation preference (highlight the block and press Ctrl-I, the default keypress for "Reindent Lines"): the second Gini lines up with c(, not with the first Gini, meaning that c( and second-Gini are at the same level ... where I would expect the second-Gini to be nested within the c(.
To validate what is going on, I'll replace the Gini(.) calls with your 0.52 and 0.73 values, verbatim (but please keep them as Gini(.) in your code:
paste0(c("Belgium, Gini ", "Croatia, Gini "),
round(c(0.52),
0.73),
digits = 2)
# [1] "Belgium, Gini 0.52" "Croatia, Gini 0.52"
Looking at it this way, it appears as if the first right-paren after 0.52 might have been intended to be after the 0.73, since grouping 0.52 and 0.73 makes sense.
Here is corrected code, where all I do is remove one right-paren from after the first-Gini, and add one right-paren to the very end of this expression:
legend=paste0(c("Belgium, Gini ", "Croatia, Gini "),
round(c(Gini(`BEL_2016_final.csv`$value),
Gini(`CRO_2016_final.csv`$value)),
digits = 2) )
and the associated matching-paren highlighting (again, _ is the current cursor):
<soapbox>
PS: I am not saying that one must use the RStudio IDE for R work. In fact, I don't, I use emacs/ess. There are other editors to use as well. However, as much as indentation and similar can be viewed as style and therefore not important for programming, I argue that indentation and some editor functionality like matching-parens can help in readability as well as troubleshooting code before you even get to a mistake; for instance, a consistent indentation style alone here hints to improper paren-closure, and the matching-paren-highlighter confirms it. Use what you prefer, but some programming styles are actually beneficial functionally (and therefore pragmatic).
</soapbox>
Correct solution is:
legend(x = "topleft", legend=paste0(c("Belgium, Gini ", "Croatia, Gini "),
c(round(Gini(`BEL_2016_final.csv`$value), digits = 2),
round(Gini(`CRO_2016_final.csv`$value), digits = 2)
)),
col=c("red", "blue"), lty=1:2, cex=1, lwd=1.5)
I made the following histogram. I want to display a stats box with a border here, like the image on this sites image, and write various information there. In addition, it is assumed that you will also write legends for multiple histograms.
As a result of research, I found that ROOT has a similar function, but I would like to realize this with R. How can I do this with R?
The xlsx file I used is large, so I uploaded it here.
library(readxl)
file = read_excel("./data.xlsx")
summary(file)
data = file[["foo[%]"]]
par(las=1, family="Century gothic", xaxs="i", yaxs="i", cex.main=3, cex.lab=1.1, cex.axis=1.1, font.lab=2, font.axis=2)
h = hist(data, yaxt="n", tck=0.03, breaks=seq(18,18.35,0.01), main=NA, xlab="xaxis", ylab="freq", border=NA, col="#00000000", ylim=c(0,100))
axis(2, tck=0.03, at=c(0,10,20,30,40,50,60,70,80,90,100))
grid()
lines(rep(h$breaks, each=2)[-c(1,2*length(h$breaks))], rep(h$counts, each=2), lwd=3)
box()
#jay.sf's suggestion is a little tricky to implement. Here's an example that comes close, but it's not perfect: the spacing is wrong. Maybe someone can improve it?
statname <- expression("Entries", "Mean", "Std Dev", chi^2/"ndf", "Prob", "Constant", "Slope")
statvalue <- expression(5000, 19.59, 18.61, 131.1/115, 0.1447, 5.54 %+-% 0.04,
-0.0514 %+-% 0.0011)
plot(1)
legend("topright", title = "hB",
legend = c(statname, statvalue),
ncol = 2,
x.intersp = 0)
Created on 2021-02-21 by the reprex package (v0.3.0)
It uses expression() for the entries because you have math in them; you might be able to do it reasonably well with special characters instead. I couldn't find a way to set the spacing of the two columns differently: your example had the names flush left and the values flush right. Nor could I set the column widths separately. Probably if you really want to fine tune this, you'll have to write your own function based on the legend function.
I am trying to plot a QTL graph with a greek symbole in my legend like this :
LOD(π,μ)
Here is my code :
plot(outFW.2p14a,lodcolumn=1:3, col = c("black","blue","green"),
ylab="LOD scores for 2014",ylim=c(0,5), main="B")
legend("topright",
legend=c("LOD(π,μ)", "LOD(π)","LOD(μ)"," ",
"LOD threshold (μ)","LOD threshold (π)","LOD threshold (π,μ)"),
col=c("black","blue","green","white","red","red","red"),
lty=c(1,1,1,1,2,3), cex=1.2)
When I use this code I get the right plot but the legend where the greek symbole π appears is wrong and show a 'p' instead...Just like this :
Legend example with error and for μ it works just fine !
I am using genetic data and tables from Rqtl package but I don't think that the problem comes from there but more from the plot function. Do you have any idea why μ works and not π ?
I would appreciate some help for this because I have tried many things and I can not get it right. I need it for a publication in a scientific journal so it needs to be right.
Best regards,
Diana
I got the symbol correctly if i use your code..
COLS=c("black","blue","green","white","red","red","red")
LABEL1 = c("LOD(π,μ)", "LOD(π)","LOD(μ)"," ",
"LOD threshold (μ)","LOD threshold (π)","LOD threshold (π,μ)")
plot(NULL,ylab="LOD scores for 2014",ylim=c(0,5), main="B",xlim=c(0,5))
legend("topright",
legend=LABEL1,
col=COLS,
lty=c(1,1,1,1,2,3), cex=1.2)
Might be something weird with your keyboard, try this, where you call the symbol through expression:
LABEL2 = c(expression(paste("LOD(",pi,",",mu,")")),
expression(paste("LOD(",pi,")")),
expression(paste("LOD(",mu,")")),
expression(paste("LOD threshold(",pi,",",mu,,")")),
expression(paste("LOD threshold (",pi,")")),
expression(paste("LOD threshold (",mu,")"))
)
plot(NULL,ylab="LOD scores for 2014",ylim=c(0,5), main="B",xlim=c(0,5))
legend("topright",
legend=LABEL2,
col=COLS,
lty=c(1,1,1,1,2,3), cex=1.2)
(I'm still learning how to handle images in R; this is sort of a continuation of rpart package: Save Decision Tree to PNG )
I'm trying to save a decision tree plot from rpart in PNG form, instead of the provided postscript. My code looks like this:
png("tree.png", width=1000, height=800, antialias="cleartype")
plot(fit, uniform=TRUE,
main="Classification Tree")
text(fit, use.n=TRUE, all=TRUE, cex=.8)
dev.off()
but cuts off a little of the labels for the edge nodes on both sides. this isn't a problem in the original post image, which I've converted to png just to check. I've tried using both oma and mar settings in par, which were recommended as solutions for label/text problems, and both added white space around the image but don't show anymore of the labels. Is there any way to get the text to fit?
The rpart.plot package plots rpart trees and automatically takes care of
the margin and related issues. Use rpart.plot (instead of plot and text in the rpart package). For example:
library(rpart.plot)
data(ptitanic)
fit <- rpart(survived~., data=ptitanic)
png("tree.png", width=1000, height=800, antialias="cleartype")
rpart.plot(fit, main="Classification Tree")
dev.off()
The default margin is 0. So if your text is a set of words or just a long word, try to put more margin in plot call. For example,
plot(fit, uniform=TRUE,margin=0.2)
text(fit, use.n=TRUE, all=TRUE, cex=.8)
Alternatively, you can adjust text font size by changing cex in text call. For example,
plot(fit, uniform=TRUE)
text(fit,use.n=TRUE, all=TRUE, cex=.7)
Of course, you can adjust both mar in plot call and cex in text call to get what you want.
On rpart man, at rpart() examples the author gives the solution, set par options with xpd = NA:
par(mfrow = c(1,2), xpd = NA)
otherwise on some devices the text is clipped
Problem tiwh titanic dataset is rplot will not join ages and fare to display a nive "age > 10" label. It will display them by extension, like:
age = 11,18,19,22,24,28,29,30,32,33,37,39,40,42,45.5,5,56,58,60...
That makes no room for labels (see the picture)
bad labels
Solution is here:
https://community.rstudio.com/t/rpart-result-is-too-small-to-see/60702/4
Basically, you have to mutate age and fare columns into numeric variables. Like:
clean_titanic <- titanic %>%
select(-c(home.dest, cabin, name, x, ticket)) %>%
mutate(
pclass = factor(pclass, levels = c(1, 2, 3), labels = c('Upper', 'Middle', 'Lower')),
survived = factor(survived, levels = c(0, 1), labels = c('No', 'Yes')),
# HERE. Also notice I'm removing dots from numbers
age = as.numeric(age),
fare = as.numeric(fare)
)
That will give you better labels, and room for them in the plot.
One more thing: you could get a warning when you force non numeric values with as.numeric, and there are a couple of ways to solve that, like replacing characters or ignoring the warning. Ignore like:
suppressWarnings(as.numeric(age)))
good plot
I'm trying to add a title at the top of the page scatterplots, however whenever I use the command title it doesn't add the title at the top of page and overwrites my plots. Is there a way to fix this ?
plot(median, pch = ".")
title(main = "Scatterplot of the median vectors ",line = 0,font=2)
Did you look at the mtext() command? Did you look at the par(oma=c(...)) option? Try something like
oldpar <- par(oma=c(0,0,2,0), mar=c(3,3,3,1), mfrow=c(1,2))
plot(cumsum(rnorm(1:100)), main="First plot", type='l')
plot(cumsum(rnorm(1:100)), main="Second plot", type='l')
mtext("Overall title", outer=TRUE, cex=1.5)
par(oldpar)
There is no reason your code should not work as is. It works for me just fine. Are you attempting to do something more than the example code you gave?
Is there a reason not to just use plot(median, pch = ".", main = "Foo")?