When creating PNG in R, the legend is cut off - r

I wrote some R code 4 years ago and haven't use R since. I am struggling to get this working again:
radio_count = data[c("a","ac","an","bn","g")]
# Create a new PNG file
png(filename=png_file, width=850, height=600, bg="white") #,antialias="cleartype")
# Expand right side of clipping rect to make room for the legend
par(xpd=T, mar=par()$mar+c(5,0,0,5),las=3)
# actually plot the bar graphs, with title
barplot( t(radio_count), main=gr_title, ylab="# of clients",col=barcolors,names.arg=data[,1],ylim=c(0,150) )
legend(36.5,100,chartlegend,cex=0.8,fill=barcolors)
grid(nx= 0, ny = NULL, col="gray60",equilogs = TRUE)
dev.off()
With 850x600, the legend is slightly clipped - meaning it only shows about 80% of the legend with the right most portion being cut off.
I need to use 1920x1080 now and the legend is not on the PNG at all.
What do I need to adjust to get the legend on the screen?

This did the trick for me:
barplot( t(radio_count), main=gr_title, ylab="# of clients", col=barcolors,
cex.main=2.2, cex.names=1.65, cex.axis=1.65, cex.lab=1.4,
names.arg=data[,1], ylim=c(0,150) )
Also note that ylim=c(0,150) tells R to make the Y axis range from 0 to 150.

Related

Move title of plots in a list of plots in R

I have a list of plots that I have assigned names to, and then converted to plot titles as suggested by https://stackoverflow.com/a/14790376/9335733. The titles happen to appear over the top x-axis title and so I attempt to move them as suggested here: https://stackoverflow.com/a/44618277/9335733. The overall code looks as follows:
lapply(names(Cast.files), function (x) plot(Cast.files[[x]],
main = x,
adj = 0, #adjust title to the farthest left
line =2.5 #adjust title up 2.5
)
)
It should be noted that plot is now converted from base R to the oce package for analyzing oceanographic data, but calls the same arguments from base R plot.
The problem becomes that in trying to move the title, the axis labels move as well and overlap. Any suggestions?
Edit: Here is what the image looks like before:
And after:
You might also want to look into the oma= argument in par(), which provides an "outer" margin which can be used to put a nice title. Something like:
library(oce)
data(ctd)
par(oma=c(0, 0, 1, 0))
plot(ctd)
title('Title', outer=TRUE)
This was solved by adding a title argument outside of the plot function as follows:
lapply(names(Cast.files), function (x) plot(Cast.files[[x]],
which = c("temperature", "salinity", "sigmaT","conductivity"),
Tlim = c(11,12),
Slim = c(29,32),
col = "red")
+ title(main = x, adj = 0.48, line = 3.5)#adding the titles at a specific location
)
This allowed for plots that looked like:
If you use the title function, rather than setting main within plot, it would allow you to change the line without affecting anything else in the plot.

plot got cut off after saving to file

My fig has a large legend outside the plot. 6 lines with long description When I save it, the legend doesn't show up. I adjusted par, but it still doesn't work.
legend("topright", inset=c(-0.6,0),xpd=TRUE,cex=0.8,
+legend=c("A_all peaks","B_ from all peaks","C_from all peaks","A_from unique peaks",
+"B_from unique peaks","C_from unique peaks",
+"A_from overlap peaks","B_from overlap peaks","C_from overlap peaks"),
+col=c("green","red","blue","lightgreen","pink","lightblue","darkgreen","darkred","steelblue"),
+pch=c(20,20,20,20,20,20,20,20,20),bty="n")
> par()$oma
[1] 2 2 2 2
> par()$mar
[1] 5.1 4.1 4.1 8.0
When save it with long width(tried 800,1000 pixel), no legend showed. But when as as short width(), part of legend shows. This is really confused me.first graph is 500*333, second graph is 500*800.
Not sure how you're saving the plot to file, but my usual routine is to make a pretty plot in R by the usual means:
plot(blah,blah,blah)
legend(blah,blah,blah)
and then once I'm happy with the appearance of the figure the R console, I use pdf() or one of it's cousins(jpeg(),tiff(), etc.) to save it to file, making sure to set the width and height parameters like so:
# set up plotting device
pdf( {{FileName}},
width = par('din')[1],
height = par('din')[2])
plot(blah,blah,blah)
legend(blah,blah,blah)
# disconnect the plotting device
dev.off()
Save it using png() or tiff():
tiff("filename",
<code for plot>,
height=5,width=7)
dev.off()
After plotting, try
% your code…
dev.copy(pdf, 'yourfile.pdf')
dev.off()
From https://statistics.berkeley.edu/computing/saving-plots-r

Output Stem and Leaf Plot to Image

I'm trying to output a Stem and Leaf plot in R as an image. I'm not sure if there's a nice library which can accomplish this but below is some of the code I've tried.
jpeg(filename="stem.jpeg",width=480,height=480, units="px",pointsize=12)
plot.new()
tmp <- capture.output(stem(men, scale = 1, width = 40))
text( 0,1, paste(tmp, collapse='\n'), adj=c(0,1), family='mono' )
dev.off()
This above code resulted in the data being saved, but it looks very blurry and the plot gets cut off pretty badly. When adding a histogram to an image, R seems to do a good job to scale everything to fit in the size of the image.
jpeg(filename="stem.jpeg",width=480,height=480,
units="px",pointsize=12)
stem(men, scale = 1, width = 40)
dev.off()
This created the image but had no content within it.
Any ideas? Thanks!
That's because stem and leaf plots produce text not images. You can save the text as follows using the sink command: http://stat.ethz.ch/R-manual/R-devel/library/base/html/sink.html
sink(file=“Stem.txt”)
stem(men, scale = 1, width = 40)
sink(file=NULL)
unlink("stem.txt")
To export a stemplot as graphics, you can use a vector graphics format, such
as .eps, .pdf, or .emf. For example, a windows metafile:
win.metafile("stem.wmf", pointsize = 10)
plot.new()
tmp <- capture.output(stem(mtcars$mpg))
text(0,1,paste(tmp,collapse='\n'),family='mono',adj=c(0,1))
dev.off()

heatmap in R how to resize columns labels?

I have a data.matrix that is approximately 4000 rows and 100 columns. I am doing a heatmap of the data like:
data<-heatmap(data_matrix,Rowv=NA,Colv=NA,col=cm.colors(256),scale="column",margins=c(5,10))
But the problem that I got is that the labels that appear in the column are too grouped, so it is impossible to visualize them correctly. How I can resize the heatmap so I can see the values of the labels of the column? I tried to print it in pdf, but it only appears a black stripe.
Thanks
I am including a figure of the heatmap, the portion that I want to see are the labels that are in the right part, but they are too close together.
First of all it's better to put your output directly to a PDF file - you may use other image formats but PDF is the best because it is a vector output and you can zoom as much as you want:
pdf("Your-file.pdf", paper="a4", width=8, height=8)
Then it's better to use pheatmap( = pretty heatmap) package. It makes really better heatmaps with a color key besides your heatmap. Finally although the pheatmap() function tries to reduce the label size while you have many rows, but it fails for really large number of rows. So I use the code below for really high - but not too high - number of rows:
library(pheatmap)
library(gplots)
if (nrow(table) > 100) stop("Too many rows for heatmap, who can read?!")
fontsize_row = 10 - nrow(table) / 15
pheatmap(table, col=greenred(256), main="My Heatmap", cluster_cols=F,
fontsize_row=fontsize_row, border_color=NA)
You may change fontsize_col for the column labels. You have many interesting options like display_numbers to have the values inside the cells of your heatmap. Just read ?pheatmap.
This is an example generated by the default parameters of pheatmap() command:
Finally note that too many rows are easy to read on a display, but useless for print.
In Rstudio you can easily resize the graphic window, same holds for Rgui. Alternatively, if you save the plot to file you can use a bigger size for your graphics, e.g. bigger width and height when calling pdf or png.
You can use cexRow = and cexCol =.
You can get more information into ??heatmap.2
# Row/Column Labeling
margins = c(5, 5),
ColSideColors,
RowSideColors,
cexRow = 0.2 + 1/log10(nr),
cexCol = 0.2 + 1/log10(nc),
labRow = NULL,
labCol = NULL,
srtRow = NULL,
srtCol = NULL,
adjRow = c(0,NA),
adjCol = c(NA,0),
offsetRow = 0.5,
offsetCol = 0.5,
colRow = NULL,
colCol = NULL
If you use pheatmap (https://www.rdocumentation.org/packages/COMPASS/versions/1.10.2/topics/pheatmap) you can spread out those labels by adjusting the cellheight parameter.
If you are doing this in R notebook, even though the entire heat map will not display in your output window when you run the code, when you save the heat map to your computer using the filename parameter, pheatmap will automatically calculate the optimal size for the output file so that your entire heatmap will be displayed in your output file. If this size is not to your liking you can adjust using width and height parameters, but it is unlikely you will want to do this.

lattice or latticeExtra combine multiple plots different yscaling (log10 and non-transformed)

I have a multiple variable time series were some of the variables have rather large ranges. I wish to make a single-page plot with multiple stacked plots of each variable were some of the variables have a log10 y-axis scaling. I am relatively new to lattice and have not been able to figure out how to effectively mix the log10 scaling with non-transformed axes and get a publication quality plot. If print.trellis is used the plots are not aligned and the padding needs some work, if c.trellis is used the layout is good, but only the y-scaling from only one plot is used. Any suggestions for an efficient solution, where I can replicate the output of c.trellis using the different y-scaling for each (original) object?
Example below:
require(lattice)
require(latticeExtra)
# make data.frame
d.date <- as.POSIXct(c("2009-12-15", "2010-01-15", "2010-02-15", "2010-03-15", "2010-04-15"))
CO2dat <- c(100,200,1000,9000,2000)
pHdat <- c(10,9,7,6,7)
tmp <- data.frame(date=d.date ,CO2dat=CO2dat ,pHdat=pHdat)
# make plots
plot1 <- xyplot(pHdat ~ date, data=tmp
, ylim=c(5,11)
, ylab="pHdat"
, xlab="Date"
, origin = 0, border = 0
, scales=list(y=list(alternating=1))
, panel = function(...){
panel.xyarea(...)
panel.xyplot(...)
}
)
# make plot with log y scale
plot2 <- xyplot(CO2dat ~ date, data=tmp
, ylim=c(10,10^4)
, ylab="CO2dat"
, xlab="Date"
, origin = 0, border = 0
, scales=list(y=list(alternating=1,log=10))
, yscale.components = yscale.components.log10ticks
, panel = function(...){
panel.xyarea(...)
panel.xyplot(...)
# plot CO2air uatm
panel.abline(h=log10(390),col="blue",type="l",...)
}
)
# plot individual figures using split
print(plot2, split=c(1,1,1,2), more=TRUE)
print(plot1, split=c(1,2,1,2), more=F)
# combine plots (more convenient)
comb <- c(plot1, plot2, x.same=F, y.same=F, layout = c(1, 2))
# plot combined figure
update(comb, ylab = c("pHdat","log10 CO2dat"))
Using #joran's idea, I can get the axes to be closer but not exact; also, reducing padding gets them closer together but changes the aspect ratio. In the picture below I've reduced the padding perhaps by too much to show the not exactness; if this close were desired, you'd clearly want to remove the x-axis labels on the top as well.
I looked into the code that sets up the layout and the margin on the left side is calculated from the width of the labels, so #joran's idea is probably the only thing that will work based on the printing using split, unless one were to rewrite the plot.trellis command. Perhaps the c method could work but I haven't found a way yet to set the scale components separately depending on the panel. That does seem more promising though.
mtheme <- standard.theme("pdf")
mtheme$layout.heights$bottom.padding <- -10
plot1b <- update(plot1, scales=list(y=list(alternating=1, at=5:10, labels=paste(" ",c(5:10)))))
plot2b <- update(plot2, par.settings=mtheme)
pdf(file="temp.pdf")
print(plot2b, split=c(1,1,1,2), more=TRUE)
print(plot1b, split=c(1,2,1,2), more=F)

Resources