barplot labels in R: add horizontal lines below the plot region - r

My code:
x <- c(10, 50, 20, 40)
barplot(x, names.arg=LETTERS[1:4])
What I want is:
I made this figure with the help of R and Adobe Acrobat. I am wondering can I obtain this figure using pure R code?

You can add text with mtext
mtext("E", side = 1, line = 3, adj = 0.375)
mtext("F", side = 1, line = 3, adj = 0.875)
and then draw line with lines but indicating xpd=T
lines(c(0,3.5),c(-10,-10),xpd=TRUE)
lines(c(3.8,4.8),c(-10,-10),xpd=TRUE)
However, you need manually adjust it.

Thanks to Pascal. I got another answer.
x <- c(10, 50, 20, 40)
barplot(x, names.arg=LETTERS[1:4])
mtext("E", side = 1, line = 3, adj = 0.375)
mtext("F", side = 1, line = 3, adj = 0.875)
axis(1, at=c(0.5,1,2,3,3.3), line=2.5, tick=T, labels=rep("",5), lwd=2, lwd.ticks=0)
axis(1, at=4+c(0.1,0.2,0.3,0.4,0.5),line=2.5,tick=T,labels=rep("",5), lwd=2, lwd.ticks=0)

Related

R double Y axis seperating

I was wondering if it is possible to seperate two plots from eachother (both should be on the same plot, using double Y axis). So the double plot should be split into two but without actually plotting them seperate - par(mfrow(1,2)).
I was trying to imitate it with layout plot, or with latticeExtra, ggplot but no success.
I have two different dataset one for the exchange rate one for the logaritmic returns.
par(mar=c(4,4,3,4))
plot(rates$EURHUF~rates$Date, type="l", ylab="Rate", main="EUR/HUF", xlab="Time")
par(new=TRUE)
plot(reteslog$EURHUF~rateslog$Date, type="l", xaxt="n", yaxt="n", ylab="", xlab="", col="red")
axis(side=4)
mtext("Log return", side=4, line=3)
legend("topleft", c("EUR/HUF Rates","EUR/HUF Logreturns"), col=c("black", "red"), lty=c(1,1))
So far I am here, I just don't know how to seperate them or scale them (maybe using margin, or layout?)
Thank you very much guys for helping
I have a solution to this that isn't too outlandish, and is entirely in base, which is nice. For it to work, you just need to be able to force all of your data onto the same scale, which usually isn't a hassle.
The idea is that once your data is on the same scale, you can plot it all normally, and then add in custom axes that show the respective scales of the different data.
set.seed(1986)
d01 <- sample(x = 1:20,
size = 200,
replace = TRUE)
d02 <- sample(x = 31:45,
size = 200,
replace = TRUE)
# pdf(file = "<some/path/to/image.pdf>",
# width = 4L,
# height = 4L) # plot to a pdf
jpeg(file = "<some/path/to/image.jpeg>") # plot to a jpeg
par(mar=c(3.5, 3.5, 2, 3.5)) # parameters to make things prettier
par(mgp=c(2.2, 1, 0)) # parameters to make things prettier
plot(x = 0,
y = 0,
type = "n",
xlim = c(1, 200),
ylim = c(1, 50),
xlab = "Label 01!",
ylab = "Label 02!",
axes = FALSE,
frame.plot = TRUE)
points(d01,
pch = 1,
col = "blue") # data 01
points(d02,
pch = 2,
col = "red") # data 02
mtext("Label 03!",
side = 4,
line = 2) # your extra y axis label
xticks <- seq(from = 0,
to = 200,
by = 50) # tick mark labels
xtickpositions <- seq(from = 0,
to = 200,
by = 50) # tick mark positions on the x axis
axis(side = 1,
at = xtickpositions,
labels = xticks,
col.axis="black",
las = 2,
lwd = 0,
lwd.ticks = 1,
tck = -0.025) # add your tick marks
y01ticks <- seq(from = 0,
to = 1,
by = 0.1) # tick mark labels
y01tickpositions <- seq(from = 0,
to = 50,
by = 5) # tick mark positions on the y01 axis
axis(side = 2,
at = y01tickpositions,
labels = y01ticks,
las = 2,
lwd = 0,
lwd.ticks = 1,
tck = -0.025) # add your tick marks
y02ticks <- seq(from = 0,
to = 50,
by = 5L) # tick mark labels
y02tickpositions <- seq(from = 0,
to = 50,
by = 5) # tick mark positions on the y02 axis
axis(side = 4,
at = y02tickpositions,
labels = y02ticks,
las = 2,
lwd = 0,
lwd.ticks = 1,
tck = -0.025) # add your tick marks
dev.off() # close plotting device
A few notes:
Sizing for this plot was originally set for a pdf, which unfortunately cannot be uploaded here, however that device call is included as commented out code above. You can always play with parameters to find out what works best for you.
It can be advantageous to plot all of your axis labels with mtext().
Including simple example data in your original post is often much more helpful than the exact data you're working with. As of me writing this, I don't really know what your data looks like because I don't have access to those objects.

When dragging the graphical device the labels don't move with the plot in R?

The following is a plotting frame for 28 plots:
par(mfcol = c(7, 4), mar = rep(.1, 4), oma = rep(7, 4))
invisible(lapply(1:28, plot, t = "n", xaxt = "n", yaxt = "n"))
To add labels to y-axis (side = 2) of the above plotting frame I do the following:
mid.y = seq(grconvertY(0 + (1 / 14), "nic"), grconvertY(1 - (1 / 14), "nic"), l = 7)
gap.y = sort(c(mid.y[-length(mid.y)] + diff(mid.y)[1L] / 2, grconvertY(0:1, "nic")))
l = c('1/10', '1/3', '1', '3', '10', '30', '100', '> 100000')
mtext(l, side = 2, at = gap.y, line = 22, cex = .9, font = 2, las = 1) # notice `line = 22
Question
The label positions are perfect. But if I drag the graphical device to the right or left the labels don't move with the plot? How can I fix the labels to move with plot (please see the following 2 pictures)?
This is a complex plotting case. Thus, for complete control use text() instead of mtext(). This way you don't need to rely on line = argument which causes the problem you describe in your question above.
Solution based on your R code above:
text(grconvertX(0, "nic"), gap.y, l, xpd = NA, adj = 1, cex = 1.3, font = 2)

Two logarithmic R plots in one diagram: Add texture or pattern + Centering the bars at zero

For the two column data available here, I am plotting two logarithmic y-axis histograms in one diagram in RStudio:
data = read.table("C:\\test\\test.csv", header=TRUE, sep=",")
par( mar=c(3.1, 5.1, 0, 0))
hist.x <- hist(data$a, plot = FALSE, breaks=50)
hist.x$counts <- log10(hist.x$counts + 1)
plot(hist.x, col = rgb(0, 0, 1, 0.99), main="", xlab="", ylab="", yaxt="n")
yAxesTitles=c(1, 10, 100, 1000, 10000)
axis(2, at=c(0, 1, 2, 3, 4),labels=yAxesTitles, col.axis="black", las=2)
mtext(side = 3, text = "a vs b", line = 0, cex=1.3)
mtext(side = 1, text = "Number", line = 2)
mtext(side = 2, text = "Frequency", line = 4)
# Adding the second diagram to the first one:
relocatedData=data$b+0.2
hist.y <- hist(relocatedData, plot = FALSE, breaks=50)
hist.y$counts <- log10(hist.y$counts + 1)
plot(hist.y, col = rgb(1, 0, 0, 0.99), main="", xlab="", ylab="", yaxt="n", add=TRUE)
legend(7.5, 4, c("a", "b"), lwd=c(1, 1), col=c(rgb(0, 0, 1, 0.99), rgb(1, 0, 0, 0.99)), pch = c(15, 15), pt.cex=2)
And this is what I have till now:
Now, there are two problems in this plot:
1- I want to add texture to the red bars (or two different patterns
for red and blue). I tried the regular texture solutions but couldn't successfully apply them in my specific diagram.
2- The space between the first bars (at 0) and the next bars (at 1) is less than other spaces (e.g., between 1 and 2, between 2 and 3 and so on). It seems that it automatically centered any two bars at each of the ticks except at 0 (which it puts both to the right side of zero).
Any solutions?

Grid line consistent with ticks on axis

I am embarrassed to ask this simple question, but has been in kicking my mind for several days whenever I create a plot:
plot (x = 1:10, y = rnorm (10, 5, 2))
grid (10,10, lty = 6, col = "cornsilk2")
I want to position the grids right at where axis are labelled, i.e. at 2, 4, 6, 8, 10 in x axis and similarly 3, 4, 5, 6, 7, 8 in y axis.
I want to automate the process as whenever the plot size changes the default label behaviour changes. See the following plot:
From ?grid description of the nx and ny arguments:
When NULL, as per default, the grid aligns with the tick marks on the
corresponding default axis (i.e., tickmarks as computed by axTicks)
plot (x = 1:10, y = rnorm (10, 5, 2))
grid (NULL,NULL, lty = 6, col = "cornsilk2")
For reference, there is a way to control the grid and axes parameters directly from the plot() command, if we are not defining a custom tick interval:
plot(x = 1:10, y = rnorm(10, 5, 2), xlim=c(1, 10), ylim=c(1, 10), panel.first=grid())
The plot.default() documentation gives more information about these parameters.
When using a custom ticks interval, the easiest is to draw the grid using abline:
plot(x = 1:10, y = rnorm(10, 5, 2), xaxp=c(1, 10, 10), yaxp=c(1, 10, 10), axes=FALSE)
axis(1, 1:10)
axis(2, 1:10)
abline(h=1:10, v=1:10, col="gray", lty=3)
More information about custom tick intervals in this thread and here for grid alignment.
For posterity, here is the long-winded way of doing it manually:
plot (x = 1:10, y = rnorm (10, 5, 2))
grid (lty = 6, col = "cornsilk2")
xaxp <- par("xaxp")
yaxp <- par("yaxp")
abline(v=seq(xaxp[1], xaxp[2], (xaxp[2]-xaxp[1])/xaxp[3]), lty=6, col = "cornsilk2")
abline(h=seq(yaxp[1], yaxp[2], (yaxp[2]-yaxp[1])/yaxp[3]), lty=6, col = "cornsilk2")
The answer provided here is much more straightforward, although you may dislike the lack of "free space" at each end of the axes. In brief,
The problem is that grid is putting nx grid lines in the user space,
but plot is adding 4% extra space on each side. You can take control
of this. Adding xaxs="i", yaxs="i" to your plot will turn off the
extra space. But then your upper right point will be cut off, so you
need to change the xlim and ylim values and change nx to match

R plotting why not starting from (0,0)?

I'm new to R programming and graphics. I'm trying to draw a graph but the (0,0) point is not at the right place. Can someone please tell me how to fix it? Thanks.
Here's my code:
layout(matrix(c(0,0,0,0,0,
0,1,3,2,0,
0,0,0,0,0), nc = 5, byrow = TRUE),
widths = c(lcm(2), 1, lcm(2), 1, lcm(2)),
heights = c(lcm(2), 1, lcm(2)))
layout.show(3)
box("outer", lty = "dotted")
plot.new()
plot.window(xlim=c(-200,0),ylim=c(0,21))
box()
axis(1)
axis(4)
rect(-113,0,0,1,col='cyan')
you can go to see 'xaxs' in ?par

Resources