I'm trying to display 4 plots in the same device window in R. I'm using Linux. However my output is far from pleasant to view.
As you can see the legend box is quite huge compared the size of the plot. I'm trying to decrease the size of the box; however I'm not able to do it. I've tried positioning the legend, box.lwd, cex, none of those gave me what I wanted.
Can anyone give me some pointers on how to decrease the size of the box of the legend?
Here is my R code:
require survival
survspec <- survfit(Surv(data1$YearEvent, data1$status) ~ data1$Vac, data1)
par(mfrow=c(2,2))
plot(survspec, mark.time=FALSE, xlab="Time (in years)", ylim=c(0.7, 1),
ylab="S(t)", col=c("royalblue", "violetred", "seagreen"))
legend(x="left",legend=c("Yes", "No", "NA"), lty=c(1, 1, 1),
col=c("royalblue", "violetred", "seagreen"))
The variable YearEvent corresponds to the x axis while the variable status is 0 or 1 and Vac can take three values. It's a Kaplan Meier plot, mainly used in survival analysis
All you need to do is use the cex set of parameters in your legend command. That will reduce the font size and I believe the symbol size (although you aren't displaying any symbols in this particular case), and thus the entire size of the legend box.
See ?par for details.
Please have a look at y.intersp parameter in legends() function. Thanks!
Related
I want to increase the font size of those percentage values inside the graph. For example, those 56%, 19%, 25%.
Current code I use
Q5 <- likert(tmp)
plot(Q5, ordered=FALSE) + theme(aspect.ratio=0.3, legend.text =element_text(color="black",size=8), axis.text=element_text(color="black",size=12))
I tried to add cex=5 inside plot function, but no effect at all.
Assuming you're using the likert package, you can set the size of the text labels with the text.size argument:
plot(Q5, text.size=5, ordered=FALSE)
You can see a description of the various options for likert plots by running ?likert.options.
I am trying to create a heatmap to represent the change of gene expression over a period of time. the code I have used is this:
coul <- colorRampPalette(brewer.pal(8, "Reds"))(25)
heatmap.2(dm, dendogram=c("row"),Colv=NA, xlab="Time points", ylab="Genes of interest", scale="row", col=coul, tracecol = NA)
As one cant really see the branches of the dendogram that well, I was wondering whether you can somehow stretch it out to become more visible?
I was also wondering how to remove the "colour key and histogram" label.
Many thanks!
if you don't mind the color guide being wide, you just use the lwid option, you specify a vector that decides the ratio of dendrogram to heatmap, below I use c(3,3), which means 1:1.
set.seed(100)
x = matrix(rnorm(1000),100,10)
heatmap.2(x,trace="none",Colv=NA,dendrogram=c("row"),tracecol = NA)
heatmap.2(x,trace="none",Colv=NA,
dendrogram=c("row"),lwid=c(3,3),tracecol = NA,keysize=0.75)
One way to narrow the margins of the color guide is to use key.par, where you set the margins on the right to be larger (I use 10 in example below).
heatmap.2(x,trace="none",Colv=NA,dendrogram=c("row"),
lwid=c(3,3),tracecol = NA,keysize=0.75,key.par=list(mar=c(3,3,3,10)))
I'm trying to visualise missing data with the R package VIM.
I'm using R version 3.4.0 with RStudio
I've used the function aggr() but the colnames of my dataframe seem to be too long. Thus, some labels of the x axis don't appear.
I would like to increase the space at the bottom of the x axis.
library(VIM)
aggr(df)
Here is my dataframe df and the plot I obtain
I've tried with par() function but it doesn't change anything.
aggr(df,mar=c(10,5,5,3))
or
par(mar=c(10,5,5,3))
g=aggr(df,plot=FALSE)
plot(g)
I can reduce the font size with cex.axis but then labels are too small.
aggr(df,cex.axis=.7)
Here is the plot with small axis labels:
I've not find a lot of examples using aggr() that's why I ask for your help.
Thank you in advance.
I think you are looking for a graphical parameter oma which will allow you to resize the main plot. The help reference states:
For plot.aggr, further graphical parameters to be passed down. par("oma") will be set appropriately unless supplied (see par).
In your case you could do something like:
aggr(df, prop = T, numbers = F, combined = F,
labels = names(df), cex.axis = .9, oma = c(10,5,5,3))
Obviously, you need to play around with cex.axis and other parameters to find out what works best for your data.
I am very new in using the power of R to create graphical output.
I use the forest()-function in the metafor-package to create Forest plots of my meta-analyses. I generate several plots using a loop and then save them via png().
for (i in 1:ncol(df)-2)){
dat <- escalc(measure="COR", ri=ri, ni=ni, data=df) # Calcultes Effect Size
res_re <- rma.uni(yi, vi, data=dat, method="DL", slab=paste(author)) # Output of meta-analysis
png(filename=path, width=8.27, height=11.69, units ="in", res = 210)
forest(res_re, showweight = T, addfit= T, cex = .9)
text(-1.6, 18, "Author(s) (Year)", pos=4)
text( 1.6, 18, "Correlation [95% CI]", pos=2)
dev.off()
}
This works great if the size of the plot is equal. However, each iteration of the loop integrates a different number of studies in the forest plot. Thus, the text-elements are not on the right place and the forest-plot with many studies looks a bit strange. I have two questions:
How can I align the "Author(s) (Year)" and "Correlation [95%CI]" automatically to the changing size of the forest-plot such that the headings are above the upper line of the forest-table?
How can I scale the size of the forest plot such that the width and the size of the text-elements is the same for all plots and for each additional study just a new line will be added (changing height)?
Each forest-plot should look like this:
Here is what you will have to do to get this to work:
I would fix xlim across plots, so that there is a fixed place to place the "Author(s) (Year)" and "Correlation [95%CI]" headings. After you have generated a forest plot, take a look at par()$usr[1:2]. Use these values as a starting point to adjust xlim so that it is appropriate for all your plots. Then use those two values for the two calls to text().
There are k rows in each plot. The headings should go two rows above that. So, use text(<first xlim value>, res_re$k+2, "Author(s) (Year)", pos=4) and text(<second xlim value>, res_re$k+2, "Correlation [95% CI]", pos=2)
Set cex in text() to the same value you specified in your call to forest().
The last part is tricky. You have fixed cex, so the size of the text-elements should be the same across plots. But if there are more studies, then the k rows get crammed into less space, so they become less separated. If I understand you correctly, you want to keep the spacing between rows equal across plots by adjusting the actual height of the plot. Essentially, this will require making height in the call to png() a function of k. For each extra study, an additional amount needs to be added to height so that the row spacing stays constant, so something along the lines of height=<some factor> + res_re$k * <some factor>. But the increase in height as a function of k may also be non-linear. Getting this right would take a lot of try and error. There may be a clever way of determining this programmatically (digging into ?par and maybe ?strheight).
So make it easier for others to chime in, the last part of your question comes down to this: How do I have to adjust the height value of a plotting device, so that the absolute spacing between the rows in plot(1:10) and plot(1:20) stays equal? This is an interesting question in itself, so I am going to post this as a separate question.
ad 4.: In Wolfgangs question (Constant Absolute Spacing of Row in R Plots) you will find how to make plot-height depending on the amount of rows in it.
For forest() it would work a little different, since this function internally modifies the par("mar")-values.
However, if you set margins to zero, you only need to include the attribute yaxs="i" in your forest()-function, so that the y-axis will be segmented for the range of the data and nothing else. The device than needs to be configured to have the height (length(ma$yi)+4.5)*fact*res with fact as inches/line (see below) and res as pixels/inch (resolution).
The 4.5 depends if you have left addfit=T and intercept=T in your meta-analysis model (in that case forest() internally sets ylim <- c(-1.5, k + 3)). Otherwise you'd have to use 2.5 (than it would be ylim <- c(0.5, k + 3)).
If you feel like using margins you would do the following (I edited the following part, after I recognized some mistake):
res <- 'your desired resolution' # pixels per inch
fact <- par("mai")[1]/par("mar")[1] # calculate inches per line
### this following part is copied from inside the forest()-function.
# forest() modifies the margin internally in the same way.
par.mar <- par("mar")
par.mar.adj <- par.mar - c(0, 3, 1, 1)
par.mar.adj[par.mar.adj < 0] <- 0
###
ylim <- c(-1.5, length(ma$yi)+3) # see above
ylim.abs <- abs(ylim[1])+abs(ylim[2])-length(ma$yi) # calculate absolute distance of ylim-argument
pixel.bottom <- (par.mar.adj[1])*fact*res # calculate pixels to add to bottom and top based on the margin that is internally used by forest().
pixel.top <- (par.mar.adj[3])*fact*res
png(filename='path',
width='something meaningful',
height=((length(ma$yi)+ylim.abs)*fact*res) + pixel.bottom + pixel.top,
res=res)
par(mar=par.mar) # make sure that inside the new device the margins you want to define are actually used.
forest(res_re, showweight = T, addfit= T, cex = .9, yaxs="i")
...
dev.off()
Does anyone know how to change the placement of the legend in color2D.matplot (plotrix)? I have a12 x 12 correlation matrix. I noticed I had to reverse the row names and change the margin to get the long names to fit. But now I am stumped on how to move the legend (without increasing the margin even more and making the graph look odd with so much white space at the bottom. Thanks!
cors<-cor(train)cellcol<-color.scale(cbind(cors,c(-1,rep(1,11))),c(0,1),0,c(1,0))[,1:12]
par(mar = c(10,8,4,2) + 0.1)
color2D.matplot(cors,cellcolors=cellcol,show.legend=TRUE,show.values=2,
axes=FALSE, xlab="",ylab="")
axis(1,at=0.5:11.5,las=2,labels=colnames(cors))
axis(2,at=0.5:11.5,las=2,labels=rev(rownames(cors)))
The help page says:
"If the default is not suitable, call color.legend separately." And then gives an example.
Based on a guess (in the absence of any information about "train" or "cors", you can try:
color.legend(0,13,6.5,14,legend=c(-1,-0.5,0,0.5,1),
rect.col=color.scale(cbind(cors,c(-1,rep(1,11))),c(0,1),0,c(1,0))[,1:12],
align="rb")