R barplot show values - r

I am plotting a barchart and face the following problem:
The barchart consists of negative and positive values. I want to show these values at the end each bar. When I choose pos=4 the positive values show up nicely but the negative ones are not so nice. When I choose pos=2 the same problem occurs vice versa...
What can I do... Please find my lines attached:
par(pin=c(9,9), mar=c(1,12,1,1), col=c(rgb(126,126,126,maxColorValue=255)), xpd=F)
PBG <- barplot(Gewicht_tsr, beside=T, horiz=T, space= c(.5,1), las=2,
cex.name=0.7, xlim=c(min(Gewicht_d)*1.7, max(Gewicht_d)*1.7),
border=NA, axes=F, main="Sektoren Gewichtung",
col=c(rgb(206,165,90,maxColorValue=255),
rgb(180,169,162,maxColorValue=255),
rgb(0,116,77,maxColorValue=255)),
col.axis=c(rgb(126,126,126,maxColorValue=255)),
col.main=c(rgb(126,126,126,maxColorValue=255)), width=.8)
legend("bottomright", legend=c("Portfolio", "Benchmark", "Aktiv"),
ncol=3, pch=15, bty="n",
col=c(rgb(0,116,77,maxColorValue=255),
rgb(180,169,162,maxColorValue=255),
rgb(206,165,90,maxColorValue=255)),
cex=0.7)
y <- (as.matrix(Gewicht_tsr [,1:ncol(Gewicht_tsr)]))
text(y,PBG, labels=as.character(y), cex=0.62, pos=4)
All other things work fine.

Related

How to customize base R plots and subplots in detail?

There is this figure in an economics paper:
I want to style my plots just like these -- with invisible top axis, Y-axis values on the right hand side, axis labels on the top of it and aligned horizontally, subplot titles aligned to the left and each subplot taller than wider and thus emphasizing change along Y-axis. I primarily use MATLAB and I tried to fiddle with it to reproduce something like this but in vain. I then reached out to one of the authors of the paper asking if he could tell which application he used for plots and if he could share how to style my plots after theirs. He responded saying he didn't have the code but he thought it was done in R.
I have not seen plots like this being done in R and even after hours of internet trawling, I didn't find anything R-generated which looked even remotely similar. Will appreciate if you folks have any thoughts/advice on whether it is indeed possible to do it in R.
EDIT
Courtesy of inputs by Isabella Ghement and after whuber's comments, I tried plotting one of the 4 by 2 panels in the figure in my question. Here is how it looks:
Ruefully, this is quite different from the panels in the question. Presumably, if I can get one panel right, I can then prepare a figure containing m by n subplots. That said, this figure has only two elements that I want -- invisible top axis and subplot title aligned to the left. But its tick marks are outside, X-axis doesn't meet the two Y-axes and axis labels are still printed vertically beside them. Here's the code that produces the above plot (taken from https://www.statmethods.net/advgraphs/axes.html, thanks Isabella Ghement for the suggestion):
# specify the data
x <- c(1:10); y <- x; z <- 10/x
# create extra margin room on the right for an axis
par(mar=c(5, 4, 4, 8) + 0.1)
# plot x vs. y
plot(x, y,type="b", pch=21, col="red",
yaxt="n", lty=3, xlab="", ylab="", bty="n")
# add x vs. 1/x
lines(x, z, type="b", pch=22, col="blue", lty=2)
# draw an axis on the left
axis(2, at=x,labels=x, col.axis="red", las=2)
# draw an axis on the right, with smaller text and ticks
axis(4, at=z,labels=round(z,digits=2),
col.axis="blue", las=2, cex.axis=0.7)
# add a title for the right axis
mtext("y=1/x", side=4, line=3, cex.lab=1,las=2, col="blue")
# add a main title and bottom and left axis labels
title("(a) Some Variable", xlab="X values",
ylab="Y=X", adj=0)
I was hoping for simple way of generating such plots but seems like it's a lot of handiwork.
FURTHER EDIT
Though one of the authors wrote back saying he thought plots were in done in R, I do suspect at this point, like #iayork, that probably they weren't done in R. I looked at online appendix of another paper in which one of the authors of the paper in this question is a coauthor and that paper too has plots of similar style. Look at this plot for example:
When I looked at file properties of that plot (it's a PDF file that comes with online appendix in a zipped folder but contains no code), I saw this:
After seeing this, I immediately thought it was generated by S-PLUS but after spending hours on end, I didn't come across anything online on S-PLUS site or any other paper which bore any resemblance. And it was then that I thought it might not be that even though it seems like so by looking at file properties. And then as a last resort, I tried to contact the authors but couldn't get anything useful yet.
You've already deactivated the yaxt, so deactivate xaxt as well. In axis we can omit the labels with labels=FALSE. May I then introduce mtext with which you can create labels independently from the axis. Yes the inward ticks are done with tck=-something. To obtain the axes touch each other we start at 0 and end slightly higher as the maximum value, overlap should be hidden automatically. Add legend. Finally it's wise to use png device to obtain desired aspect ratio. I think that's it, in a nutshell?
# specify the data
x <- c(0:10); y <- ((x^2)-20)/100; z <- (100/x-3)/100
# helper variables
t.adj <- .03
y.seq <- c(-.5, seq(0, 1.5, length.out=4))
png("ecn.plot.png", width=400, height=500)
# margins
par(mar=c(4, 4, 4, 5) + 0.1)
# plot x vs. y
plot(x, y,type="l", pch=21, col="red", xlim=c(0, 10), ylim=c(-.42, max(y.seq)),
yaxt="n", xaxt="n", lty=1, xlab="", ylab="", bty="n", lwd=2)
# add x vs. 1/x
lines(x, z, type="l", pch=22, col="blue", lty=2, lwd=2)
# add y-zero line
abline(h=0, lwd=2)
# draw axes
axis(1, at=(-1:6)*2,labels=FALSE, col.axis="black", tck=t.adj, lwd=2)
mtext((0:5)*2, 1, 0, at=(0:5)*2,col.axis="black", font=2)
axis(2, at=y.seq, labels=FALSE, col.axis="red", las=2, tck=t.adj, lwd=2)
axis(4, at=y.seq, labels=FALSE, col.axis="red", las=2, tck=t.adj, lwd=2)
mtext(formatC(sort(c(0, y.seq)), digits=1, format="f"), 4, 2,
at=sort(c(0, y.seq)), col="black", las=2, font=2, adj=1)
mtext("pct.", 4, 0, at=max(y.seq)+.15, las=2, adj=1, font=2, cex=.9)
# add title
mtext("(a) Some Variable", padj=-2, adj=0, cex=1.2, font=2)
# add legend
legend(x[2], max(y.seq), c("Home", "Foreign"), lty=c(1, 2),
col=c("red", "blue"), bty="n", cex=.8)
dev.off()
Result
Ah, for the arranging of multiple plots you may want to look at this answer.

Placing an x axis on top of a bar plot with negative y values

I have some data for various experimental treatments which are negative values. I'd like to plot the x-axis on top of the bar-plot and have the labels located the same as if it were a traditional bar-plot at the centre of the bars.
I've checked all over and can't find anything that lets me name the axis labels with words, only setting tick marks and numbers.
Here's the data: - "wp_means"
> 12 15 3 6 9 Control
-0.3000000 -0.2416667 -0.3416667 -0.3916667 -0.2750000 -0.2750000
DL
-0.2833333
Here's my code to plot the bar-plot. I can omit the x-axis from it's usual position, but I can't seem to get it on top with its labels etc. where I want it to be.
cols<-c("blue1", "cyan","chartreuse","mediumspringgreen","maroon1","orange","red")
wp<-data.frame(a=c(wp_means),b=c(12,15,3,6,9,"Control","DL"))
wp$c=factor(wp$b, levels = c("Control",15,"DL",12,9,6,3))
wp <- wp[order(wp$c), ]
barplot(height=wp$a,names.arg=wp$c,col=cols,main="Water Potential",las=1,xaxt="n",
ylab = "Water potential
(MPA)",pch=21,bg="black",cex=0.7,cex.lab=0.8,font.lab=2,
cex.axis=0.7,font.axis=2,cex.main=1,ylim=c(-0.5,0),xaxt="n")
And here's the plot: I'd like to have the labels on the upper x axis in the order they appear in "levels = c("Control"....)" per above. I'd also like to set a label title the same way one would usually do with xlab="some name" without it interfering with my chart title.
Thanks
The appropriate method I believe is to use the pos= argument when adding an ?axis to your existing barplot. You will need to save the positions of the bar centres first however. Like bp <- barplot(...), so:
wp_means <- c(-0.3, -0.2, -0.34, -0.39, -0.275, -0.275, -0.283)
cols<-c("blue1", "cyan","chartreuse","mediumspringgreen","maroon1","orange","red")
wp <-data.frame(a=c(wp_means),b=c(12,15,3,6,9,"Control","DL"))
wp$c=factor(wp$b, levels = c("Control",15,"DL",12,9,6,3))
wp <- wp[order(wp$c), ]
bp <- barplot(height=wp$a, names.arg=wp$c, col=cols, las=1, xaxt="n",
ylab = "Water potential (MPA)",
pch=21, bg="black", cex=0.7, cex.lab=0.8, font.lab=2,
cex.axis=0.7, font.axis=2, cex.main=1, ylim=c(-0.5,0), xaxt="n")
axis(side=3, pos=0, at=bp, labels=levels(wp$c))
title(main="Water Potential", line=3)
Note the use of line=3 when adding a title() which pushes your chart title away from the group labels.

Add the bars difference values on the top of each bar groups in R

I have a group bar plot that shows three different metrics for two algorithms.
How can I add the percentage of increase/decrease between this two different algorithms on the top of each bar? For example, on the top of the precision bar, we should have -0.017 and for the coverage bar we should have +0.3867 on the top.
Here is my R code:
als_precision<-0.27069
als_ndcg<-0.1523
als_coverage<-362/3233
als_reg_precision<-0.2659
als_reg_ndcg<-0.1520
als_reg_coverage<-502/3233
barplot(matrix(c(als_precision,als_reg_precision,als_ndcg,als_reg_ndcg,als_coverage,als_reg_coverage),nr=2), beside=T,
col=c("red","blue"),
names.arg=c("Precision#10","NDCG#10","coverage"))
legend("topright", c("ALS","ALS+reg"), pch=15,
col=c("red","blue"),
bty="n")
You can use text to add the text to the plot.
Edit The original did not use the percentage change.
barplot(matrix(c(als_precision,als_reg_precision,als_ndcg,als_reg_ndcg,
als_coverage,als_reg_coverage),nr=2), beside=T,
col=c("red","blue"), ylim=c(0,0.30),
names.arg=c("Precision#10","NDCG#10","coverage"))
legend("topright", c("ALS","ALS+reg"), pch=15,
col=c("red","blue"),
bty="n")
text(2, max(als_precision, als_reg_precision)+0.01,
round((als_reg_precision - als_precision)/als_precision,3))
text(5, max(als_ndcg, als_reg_ndcg)+0.01,
round((als_reg_ndcg - als_ndcg)/als_ndcg,3))
text(8, max(als_coverage, als_reg_coverage)+0.01,
round((als_reg_coverage - als_coverage)/als_coverage,3))

R: two axes and grid lines

I would like to plot two graphs in the same plotting region with horizontal grid lines. Each side of the grid lines should give the value for one graph or the other. There should be no y-axis.
The grid() function allows me to simply set the number of bins using the ny= argument. How do I get the corresponding labels to the grid lines? Usually, I would use axis(..., lwd=0) to get the labels. However, the function requires label positions with at=c() and does not feature a ny= argument. Is there a way to automatically set the locations from the number of bins?
Based on Miff's hint below, this should solve the problem.
plot(1:10, axes=FALSE, ylim=c(0,10), ylab="")
par(yaxp=c(0, 10, 5))
axis(2, lwd=0, col.axis="gray")
par(new=TRUE)
plot(60:50, axes=FALSE, ylim=c(50,60), ylab="")
par(yaxp=c(50, 60, 5))
axis(4, lwd=0, col.axis="gray")
grid(NA, NULL)
grid() gets its locations for gridlines from axTicks(), which in turn uses numbers from par("yaxp"). If you modify this parameter (rather than explicitly passing it to grid), the result will then apply to both the grid drawn and the axis. For example:
plot(1:10, axes=FALSE)
axis(2) #Default 4 sections between ticks
par(yaxp=c(par("yaxp")[1:2], 7)) #Lets have seven instead
axis(4)
grid() #Grid now matches with right rather than left
Obviously similar works for the x axis.

Overlay custom axes to a plot created by symbols

Struggling with this one. I have 25 data items that I want plotted with bubbles in 5 columns.
The plot can be re-created thus:
xcord <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5)
ycord <- c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5)
zsize <- c(2,1,2,3,6,8,9,1,4,5,5,6,7,8,8,9,5,5,5,5,1,8,1,1,12)
Save the parameters before I change them:
op <- par()
dev.off()
Change the parameters:
par (mfrow=c(1,0), mar=c(2,2,2,2), oma=c(2,2,2,2))
Plot using symbols:
symbols(xcord, ycord, zsize, inches=0.3, fg="white", bg="red", xlab="Events", ylab="Diagnoses", tck=0, xaxt="n", yaxt="n")
mtext("Rheumatic diagnoses by cerebrovasular events", line=2, font=2, cex=1.2)
I am happy with the above plot and deliberately used tck=0, xaxt="n", yaxt="n" to clear the axes. I want to manually overlay custom text, controlled with custom co-ordinates (which work with the sysmbols plot), but have not been able to do it. I have tried some of the par arguments and the axes function.
I also tried leaving the axes on:
symbols(xcord, ycord, zsize, inches=0.3, fg="white", bg="red", xlab="Events", ylab="Diagnoses")
but do not know how to change the output (1,2,3,4,5) to my own custom axes labels.
Thank you.
You are looking for the axis function (see ?axis for details), e.g. to replace the 1:5 with A, B, C, D, E:
axis(side=1, at=1:5, labels=LETTERS[1:5])

Resources