How to remove decimal letter from charts in R code? - r

I am trying to pull charts (.png) from the data from SQL Server using ODBC in R. The code is running fine but label on y-axis is in decimals. eg. 10.0%, 20.0%, 30.0%, 40.0% and 50.0%.
I do not want this in decimal place on y-axis. Please help me to get rid of this issue.
Please see my below code and help me with this issue.
Output Chart
# produce plots for all the pids
for (i in 1:n_pids){
print(paste0('working on ', i, ' pid ', def_dates$pid_names[i]))
pidx <- def_dates[i,'pid']
sub <- res[pid == pidx]
png(file = paste0(pidx, '-misrated.png'), width = 750, height = 350, units = "px", pointsize = 12 )
par(oma = c(5, 1,1,1), mar=c(0,3,3,3))
with(sub, plot(date, edf1/100,
type="l", col="blue",
ylim=c(0,.5), bty='n',
xlab=NA, ylab=NA, cex=0.9,lwd=2,
axes=F,xaxs = "i",yaxs="i",
panel.first =
c(abline(h = seq(0,1,.1), lty = 2, col = 'grey')
,NULL)
))
abline(v=as.Date(def_dates[def_dates$pid == pidx,'def'],'%m-%d-%Y'),
col="red",lwd=2)
axis.Date(1, at = seq(min(sub$date), max(sub$date), length.out = 10),
format= "%b %Y") # bottom dates
var1= seq(0,0.5,.1)#pretty_breaks(n=5)(sub$edf1/100)
axis(2, lwd=0,
at=var1,
label=percent(var1),
las=1) # EDF values
par(new=T)
with(sub, plot(date, displaystring, type="l",
col="darkgreen", lwd=2,
axes=F, xlab=NA, ylab=NA))
axis(side = 4,
at=seq(1,NROW(unique(sub$displaystring))),
labels=unique(sub$displaystring),
lwd=0,cex=0.5,las=1,
col="darkgreen"
)
par(oma = c(0,0,0,0))
legend("bottom", legend=c("DENBURY RESOURCES INC [1-Yr EDF9]","MIS RATING"), xpd = TRUE,
horiz = TRUE,
inset = c(0,0), bty = "n",
col=c("blue", "darkgreen"), lty=1, cex = 1)
dev.off()
#ggsave(paste0(pidx, '-rated.png'), p, scale=3, height=3, width=6, unit="in")
}

I can't vouch for the rest of the code, but the only portion that has affect on the y-axis here is:
axis(2, lwd=0,
at=var1,
label=percent(var1),
las=1) # EDF values
When you find scales::percent, the help page does not appear to give an easy way to control the decimal places. I suggest we use good-ole sprintf for this.
scales::percent(var1)
# [1] "0.0%" "10.0%" "20.0%" "30.0%" "40.0%" "50.0%"
sprintf("%0.0f%%", 100*var1)
# [1] "0%" "10%" "20%" "30%" "40%" "50%"
So your resulting code will be:
axis(2, lwd=0,
at=var1,
label=sprintf("%0.0f%%", 100*var1),
las=1) # EDF values

Related

How to find y value in line-and-dots plot?

I have this line-and-dots plot:
#generate fake data
xLab <- seq(0, 50, by=5);
yLab <- c(0, sort(runif(10, 0, 1)));
#this value is fixed
fixedVal <- 27.3
#new window
dev.new();
#generate the plot
paste0(plot(xLab, yLab, col=rgb(50/255, 205/255, 50/255, 1), type="o", lwd=3,
main="a line-and-dots plot", xlab="some values", ylab="a percentage",
pch=20, xlim=c(0, 50), ylim=c(0, 1), xaxt="n", cex.lab=1.5, cex.axis=1.5,
cex.main=1.5, cex.sub=1.5));
#set axis
axis(side = 1, at=c(seq(min(xLab), max(xLab), by=5)))
#plot line
abline(v=fixedVal, col="firebrick", lwd=3, lty=1);
now, I would like to find the y coordinate of the intersection point between the green and the red lines.
Can I achieve the goal without the need of a regression line? Is there a simple way of getting the coordinates of that unknown point?
You can use approxfun to do the interpolation:
> approxfun(xLab,yLab)(fixedVal)
[1] 0.3924427
Alternatively, just use approx:
> approx(xLab,yLab,fixedVal)
$x
[1] 27.3
$y
[1] 0.3924427
Quick fix like #JohnColeman said:
# find the two points flanking your value
idx <- findInterval(fixedVal,xLab)
# calculate the deltas
y_delta <- diff(yLab[idx:(idx+1)])
x_delta <- diff(xLab[idx:(idx+1)])
# interpolate...
ycut = (y_delta/x_delta) * (fixedVal-xLab[idx]) + yLab[idx]
ycut
[1] 0.4046399
So we try it on the plot..
paste0(plot(xLab, yLab, col=rgb(50/255, 205/255, 50/255, 1), type="o", lwd=3,
main="a line-and-dots plot", xlab="some values", ylab="a percentage",
pch=20, xlim=c(0, 50), ylim=c(0, 1), xaxt="n", cex.lab=1.5, cex.axis=1.5,
cex.main=1.5, cex.sub=1.5));
#set axis
axis(side = 1, at=c(seq(min(xLab), max(xLab), by=5)))
#plot line
abline(v=fixedVal, col="firebrick", lwd=3, lty=1);
abline(h=ycut, col="lightblue", lwd=3, lty=1);

starting the y-axis at a minimum value, the x-axes at 0, and making them intersect using matplot() in R

In this question it says my current question was answered by this question; however the code suggested doesn't go far enough for me. These charts need to be suitable for scientific publication, so the effect of yaxs = "i" and xaxs = "i" is not suitable for what I need to produce.
The charts displayed in the second link look great, and would be up to the job that I am after, however when I use a similar code for data that does not start at 0:
matplot(times, cbind(a, b, c),
pch = 1,
col = c("red", "blue", "green"),
lty = c(1, 1, 1),
xlab = "Time (s)",
ylab = "Flourescense Yield (RFU)",
main = "test",
xlim = c(0 , max(times)),
ylim = c(min(a, b, c) - 0.1* min(a, b, c), max(a, b, c) + 0.1* max(a, b, c)),
axes = FALSE)
axis(1, pos = 0, at = 0: round(times))
axis(2, pos = 0, at = round(min(a, b, c)): round(max(a, b, c)))
legend("topright", y =NULL, c("Biocomposite 1", "Biocomposite 2", "Biocomposite 3"),
text.col = c("red", "blue", "green"))
I get the following chart:
I have simplified the code so I don't use my actual data, and I am using the following objects:
a <- sample(1:100, 10, replace = TRUE)
b <- sample(1:100, 10, replace = TRUE)
c <- sample(1:100, 10, replace = TRUE)
times <- c(0:9)
What I would like is to have the axes to cross at (0,6), and horizontal tick points to increment in multiples of 5.
Any help with sorting this would be great!
Do either of the following get at what you're after?
Approach 1: Regular axes (xaxs='r'), with a box?
dev.new()
par(xaxs="r", yaxs="r")
plot(times, a, pch=1, col="red", axes=F, xlab=NA, ylab=NA)
axis(side=1, at=times)
mtext("Times (s)", side=1, line=2.5)
axis(side=2, at=seq(0,100,10))
mtext("Flourescense Yield", side=2, line=2.5)
points(times, b, col="blue")
box()
Approach 2: Or tighter axes (xaxs='i'), but with slightly exaggerated x and y limits and a box?
dev.new()
par(xaxs="i", yaxs="i")
plot(times, a, pch=1, col="red", axes=F, xlab=NA, ylab=NA,
xlim=c(-.5,9.5), ylim=c(-2,102))
axis(side=1, at=times)
mtext("Times (s)", side=1, line=2.5)
axis(side=2, at=seq(0,100,10))
mtext("Flourescense Yield", side=2, line=2.5)
points(times, b, col="blue")
box()

How to shift bars from y-axis using barplot() R

I have a barplot with the following code:
bp <- barplot(COL0.matrix,
beside=T,
col=col,
ylim=c(0,100), yaxt="n",
xlab="Time",ylab="Relative Electrolyte Leakage (%)",
las=1,xaxt = "n",
cex.axis=1.5, cex.names= 1.5, font=2, font.lab=2, cex.lab=1.5, family="A", space=c(0,0,1,0), xaxs = 'i')
axis(side=2, family="A", cex.axis=0.8, las=1, font=2, pos=0, tck=c(0), at=c(0,10,20,30,40,50,60,70,80,90,100), labels=c("0", "10","20","30","40","50","60","70","80","90","100"))
axis(side=2, at=c(0,10,20,30,40,50,60,70,80,90,100), labels = c(NA),tcl=c(-0.25),pos=0)
axis(side=2, at=c(0,10,20,30,40,50,60,70,80,90,100), labels = c(NA),tcl=c(0.25),pos=0)
axis(side=1, at=c(1.2, 4.2), labels = c("Dawn", "Dusk"),tck=c(0), family="A", cex.axis=1.5, font=2, pos=0)
This results in the following barplot:
I am trying to shift the bars which are right next to the y-axis away. I have tried changing space=(...) but this shifts the whole x-axis so that the x and y axis no longer join.
Is there a way of shifting the left two bars over?
You can use the line parameter to move the axis over instead of moving the bars. You want to remove the pos = 0 and define the y title outside the barplot function so you can also control its position. Also you will want to play with the par(mar = ... part so it looks right for your device. For if you save in a pdf device your margin and even the cex parameters probably will need adjusting to make it nice. Also I set the graphics parameter xpd = TRUE to allow the lines function in the last line to plot into the margin space. If you don't do that you'll have a x axis that doesn't meet the y axis. If you don't want that then remove the last line.
COL0.matrix <- structure(c(71.44109964, 78.43178612, 64.31581642, 70.3339388 ), .Dim = c(2L, 2L), .Dimnames = list(c("Control", "bold(\"Col-0 840g ha\"^\"-1\")" ), c("Dawn", "Dusk")))
col = c("white", "grey70", "white", "grey70")
par(mar = c(5,7,5,5), xpd = TRUE)
bp <- barplot(COL0.matrix,
beside=T,
col=col,
ylim=c(0,100), yaxt="n",
xlab="Time", ylab = "",
las=1,xaxt = "n",
cex.axis=1.5,
cex.names= 1.5,
font=2,
font.lab=2,
cex.lab=1.5,
family="A",
space=c(0,0,1,0),
xaxs = 'i')
mtext("Relative Electrolyte Leakage (%)", side = 2, font = 2, cex = 1.5, line = 4)
axis(side=2, family="A", cex.axis=0.8,
las=1, font=2, tck=c(0),
at=c(0,10,20,30,40,50,60,70,80,90,100),
labels=c("0", "10","20","30","40","50","60","70","80","90","100"),
line = 1)
axis(side=2, at=c(0,10,20,30,40,50,60,70,80,90,100), labels = c(NA),tcl=c(-0.25), line = 1)
axis(side=2, at=c(0,10,20,30,40,50,60,70,80,90,100), labels = c(NA),tcl=c(0.25), line = 1)
axis(side=1, at=c(1.2, 4.2), labels = c("Dawn", "Dusk"),tck=c(0), family="A", cex.axis=1.5, font=2, line = 0)
lines(x = c(-0.3, 5.3), y = c(0, 0))

Plots side by side in R. Controling size accurately

I need to put 2 columns of plots side by side (only one row in the example) and I can't manage to control the size of the plots and the position of the labels so that both plots are exactly aligned. This is the code the have now:
split.screen(c(1,2))
screen(1)
par(oma=c(0,1,0,0), mai=c(0.6,0.36,0.5,0.7), cex=0.5, mgp = c(0.5,0.1, 0), tck = -0.05)
plot(datos$UN.CJF*1000, datos$Methane.Produced.CJF, pch = 16, cex = 0.5, col ="black",
xlab = "UN (g/d)", ylab = expression('CH'[4]*'(g/d)'))
title(main = "a)", cex=0.8, line=0.5, adj=0, cex.lab=1.2)
datos$LWchangeD.CJF <- datos$LWchange.CJF/15
screen(2)
par(oma=c(0,1,0,0), mai=c(0.6,0.36,0.5,0.7), cex=0.5, mgp = c(0.5,0.1, 0), tck = -0.05)
scatter2D(datos$UN.CJF*1000, datos$Methane.Produced.CJF,
pch = 16,
xlab = "UN (g/d)", ylab = "",
colvar = datos$LWchangeD.CJF, clab = c("Liveweight change (kg/d)")
)
title(main = "b)", cex=0.8, line=-0.7, adj=0, cex.lab=1.2)
Notice how the size of the 2 figs is different
There must be a better way to do it.
Any help would be MUCH appreciated
Alvaro
grid.arrange did the trick, but I first re-did all my plots in ggplot2.
Thanks a lot for your suggestions
Alvaro

R plot, change scale of values for plot axis

I am doing a plot with R, the code for stacked bar and axis 2 are simple, here is the code for line and axis 4:
lines(y,
theLineValues,
type = "o",
pch = 20,
lwd = 2,
cex = 1.2,
lty = 1,
col ="forestgreen")
axis(4,
at = getYaxis(0,1,0.01, 3), # function to get 3 values for axis
labels = getYaxis(0,1,0.01, 3),
col.axis= "forestgreen",
las = 1,
cex.axis= 0.7,
col = "forestgreen",
line = 0)
then I found the min and max value: 0.46, 0.68 , and want to use them as axis, so the changing of line can be seen more obviously(the red line).
labels = getYaxis(min(theLineValues),max(theLineValues),0.01,3),
How would I scale the 'theLineValues' to do this?
Thanks.
======================================================================
Update 1: the code for 'y':
y <- barplot(
combinedvalues, # it's list of 3-combined values.
col = c("slategray1","darkseagreen1","moccasin"),
beside = FALSE,
border = "grey80",
las = 1,
cex.axis= 1.0,
ann = FALSE,
ylim = c(0,1),
yaxt = "n")
======================================================================
Update 2: the combined values:
these values are in .csv file, and use the following to get the 'combinedvalues' and pass it to 'y':
rbind(csv$frame0,csv$frame1,csv$frame2)
# frame0+frame1+frame2 shoud be 1, theLineValues were calculated by some formulas.
the csv file:
frame0 frame1 frame2 theLineValues
------------------------------------------------------------
0.4460203874 0.2271394791 0.3268401336 0.4674583872
0.4473756948 0.2084173711 0.3442069341 0.4796977238
0.5296042291 0.1570493286 0.3133464423 0.570317484
0.5255498752 0.1234146373 0.3510354875 0.6095475721
0.5405768621 0.119299957 0.3401231808 0.6251561825
0.5657840709 0.0916650587 0.3425508703 0.6896446583
0.4826617968 0.0877739789 0.4295642243 0.6610089801
0.3588171226 0.122977733 0.5182051444 0.606129318
0.2608499204 0.1705417922 0.5686082874 0.595971676
0.2111782825 0.2040231107 0.5847986067 0.6057364576
0.1731616573 0.240909341 0.5859290016 0.6153720603
Thanks.
======================================================================
Update 3: the final plot:
Frames.txt is based on the three frame columns.
Data
frames <- read.table("/your-path/frames.txt",header=T,na.string="NA")
theLineValues<-c(0.4674583872, 0.4796977238, 0.570317484, 0.6095475721, 0.6251561825, 0.6896446583, 0.6610089801, 0.606129318, 0.595971676, 0.6057364576, 0.6153720603)
Plot
barplot(t(frames), , col = c("slategray1","darkseagreen1","moccasin"))
axis(2, ylim=c(0,1))
mtext("barplot values", side=2, line=2)
box()
par(new=TRUE)
plot(theLineValues, type = "l", pch = 20, xlab="", ylab="", col = "forestgreen", lwd=2, ylim=c(min(theLineValues), max(theLineValues)), axes=FALSE)
axis(4, ylim=c(min(theLineValues), max(theLineValues)))
mtext("lineValues", side=4, line=0.2)
box()

Resources