how to confine plot region at exactly area - r

For example, I would like to plot a box with grids inside, the code show below:
plot(rnorm(10), rnorm(10), type = "n", asp = 1, xlim = c(0, 1), ylim = c(0, 1), axes = FALSE, pty = "s", bty = "o", xlab = "", ylab = "")
abline(h = seq(0, 1, 0.2), v = seq(0, 1, 0.2), col = "lightgray")
abline(a = 0, b = 1, col = "lightgray")
axis(1, seq(0, 1, 0.2), seq(0, 1, 0.2), pos = 0)
axis(2, seq(0, 1, 0.2), seq(0, 1, 0.2), pos = 0)
But the lines exceed the area (0, 0) to (1, 1), just like box with whisker. It may be the problem with plot region, and how can I confine the plot region to exactly area for example from (0, 0) to (1, 1)?
Thanks a lot!

plot(rnorm(10), rnorm(10), type = "n", asp = 1, xlim = c(0, 1), ylim = c(0, 1),
axes = FALSE, pty = "s", bty = "o", xlab = "", ylab = "")
axis(1, seq(0, 1, 0.2), seq(0, 1, 0.2), pos = 0)
axis(2, seq(0, 1, 0.2), seq(0, 1, 0.2), pos = 0, las=1)
You can use clip to prevent annotations extending beyond the clip region. The four arguments determine the two coordinates of the rectangle for clipping.
clip(0,1,0,1)
abline(h = seq(0, 1, 0.2), v = seq(0, 1, 0.2), col = "lightgray")
abline(a = 0, b = 1, col = "lightgray")

Related

Rotate plot 90deg for marginal distribution

I am trying to get marginal distribution plots in base R (if not possible, non-base R code is okay, but only for doing the rotating).
How do you rotate the y-axis marginal plot (in yellow)?
The code I have to make this plot:
# plot layout
layout_mat <- matrix(c(2, 0,
1, 3),
nrow = 2,
byrow = T)
layout(layout_mat, c(3, 1), c(1, 3))
par(mar = c(3,3,1,1))
# main scatterplot
plot(x = mtcars[order(mtcars$qsec), c("wt", "mpg")],
xlab = "Vehicle Weight (1000 lbs)",
ylab = "Miles Per Gallon (MPG)",
pch = 16,
cex = seq(3.5, 1.25, length.out = nrow(mtcars)),
col = rgb(0, 0, 0, .5),
axes = F,
xlim = c(1, 6),
ylim = c(8, 35))
box(lwd = 1.5)
axis(side = 1, at = 1:6, labels = 1:6, lwd = 0, lwd.ticks = 1)
axis(side = 2, at = seq(10, 35, 5), label = seq(10, 35, 5), lwd = 0, lwd.ticks = 1, las = 1)
dx <- density(mtcars[order(mtcars$qsec), "wt"])
dy <- density(mtcars[order(mtcars$qsec), "mpg"])
# x axis plot
par(mar = c(0,3,1,1))
plot(dx, axes = F, main = "", xlab= "", ylab = "", lwd =2)
# y-axis plot
par(mar = c(3,0,1,1))
plot(dy, axes = F, main = "", xlab= "", ylab = "", lwd =2)
rect(xleft = par("usr")[1],
ybottom = par("usr")[3],
xright = par("usr")[2],
ytop = par("usr")[4],
col = rgb(235, 216, 52, .5*255, maxColorValue = 255))
Thanks to #user20650 for this answer
Passing the y-axis points for y's density to x and the x-axis points for y's density to y will plot it flipped:
plot(dy$y, dy$x, type="l", axes = F, main = "", xlab= "", ylab = "", lwd = 2)

Plot a simple coordinate systems with vectors

How could I create a simple plot of a coordinate system within two vectors in R? It should look like the following plot.
Thank you!
# Empty plot
plot(1, 1, type = "n", xlim = c(-3, 3), ylim = c(-3, 3), asp = 1,
ann = FALSE, axes = FALSE)
# Axes
arrows(x0 = -3, y0 = 0, x1 = 3, y1 = 0, length = 0.1, code = 3)
arrows(x0 = 0, y0 = -3, x1 = 0, y1 = 3, length = 0.1, code = 3)
# Vectors
# v1
arrows(0, 0, 2.5, 1, length = 0.1, col = "lightblue", lwd = 2)
# v2
arrows(0, 0, 1, 2, length = 0.1, col = "blue", lwd = 2)
# v3
arrows(1, 2, 2.5, 1, length = 0.1, col = "red", lwd = 2)
# Text
text(x = mean(c(0, 2.5)), y = mean(c(0, 1)), labels = "v1", pos = 1)
text(0.5, 1, "v2", pos = 3)
text(1.75, 1.5, "v3", pos = 4)

How to make the trend-line in a scatter plot respect the boundaries of the x-axis?

I am creating a plot where I plot the variable on the X-axis against that on the Y-axis, and I am adding histograms of the variables as well. I have added a trend-line to the plot using abline().
The problem is that it does not appear to respect the xlim = c(0, 20) in the plot region as it extends beyond the limits of the x-axis. I tried playing around with the xpd option, but to no avail. Next I tried fiddling with the different par()options, but found nothing that could help with this issue.
What I want is for the trend-line to be the exact length of the x-axis. Any help is much appreciated. In this particular case the trend-line is almost flat, but the slope will change when I do the same for other variables.
MWE -- NOTE: I am only providing 15 data points to illustrate the issue so the graph will differ from the image provided.
df.data <- data.frame(id = 1:15,
ll = c(-9.53026, -6.50640,-6.50640, -7.68535, -11.80899, -8.42790,
-6.50640, -6.50640, -7.92405, -6.50640, -8.95522, -9.99228,
-10.02286, -8.95969, -6.07313),
aspm = c(4.582104, 0.490244, 0.737765, 0.256699, 1.575931, 1.062693,
1.006984, 0.590355, 1.014370, 0.924855, 0.735989, 0.831025,
1.197886, 1.143220, 0.928068))
str.col.light.blue <- c(rgb(r = 110/255, g = 155/255, b = 225/255))
str.col.dark.blue <- c(rgb(r = 50/255, g = 100/255, b = 185/255))
layout(matrix(c(2, 4, 1, 3), 2, 2, byrow = TRUE), widths = c(5, 2), heights = c(2, 5))
layout.show(4)
par(omi = c(0.1, 0.1, 0.1, 0.1))
par(mar = c(2, 2, 0, 0))
par(mai = c(1, 1, 0, 0))
plot(df.data[, "ll"] ~ df.data[, "aspm"], col = str.col.light.blue,
xlim = c(0, 20), ylim = c(-15, -5), axes = FALSE,
xlab = "X1", ylab = "X2",
cex.lab = 1.25)
abline(a = -8.156670, b = -0.000879, lty = 5, col = "black", lwd = 2, xpd = FALSE)
axis(1, at = seq(0, 20, by = 5), labels = seq(0, 20, by = 5), cex.axis = 1)
axis(2, at = seq(-15, -5, by = 3), labels = seq(-15, -5, by = 3), cex.axis = 1, las = 1)
rect(0, -15, 20, log(1/3)*8, density = 10, angle = 45, lwd = 0.5, col = "gray")
par(mar = c(0, 2, 0, 0))
par(mai = c(0, 1, 0.25, 0))
x.hist <- hist(df.data[, "aspm"], plot = FALSE, breaks = 20)
barplot(x.hist$density, axes = FALSE, horiz = FALSE, space = 0, col = str.col.dark.blue)
par(mar = c(2, 0, 0, 0))
par(mai = c(1, 0, 0, 0.25))
y.hist <- hist(df.data[, "ll"], plot = FALSE, breaks = 20)
barplot(y.hist$density, axes = FALSE, horiz = TRUE, space = 0, col = str.col.dark.blue)
In order to avoid working out the start and end points of the segments, you can program a helper function to do it for you.
linear <- function(x, a, b) a + b*x
Then, I've used your code with the following changes. abline was replaced by segments, with all the graphics parameters you had used in your original call.
x0 <- 0
y0 <- linear(x0, a = -8.156670, b = -0.000879)
x1 <- 20
y1 <- linear(x1, a = -8.156670, b = -0.000879)
segments(x0, y0, x1, y1, lty = 5, col = "black", lwd = 2, xpd = FALSE)
This call to segment was placed where ablinewas.
In the final graph, I see a well behaved segment.

Multiple 2D background plots in RGL

I'm trying to put multiple background legends on an rgl plot (in my real-world example, one for lines and one for points), and I would like them to be in different corners of the screen. It seems that the default behavior of rgl is to replace an older legend when a new one is called. The following code, modified from the rgl legend3d example, illustrates this:
library(rgl)
x <- rnorm(100)
y <- rnorm(100)
z <- rnorm(100)
open3d()
par3d(windowRect = c(100, 100, 612, 612))
plot3d(x, y, z)
legend3d(x = 0, y = 0, xjust = 0, yjust = 0, legend = c("2D", "3D"), pch = c(1, 16))
legend3d(x = 1, y = 0, xjust = 1, yjust = 0, legend = c("2D", "3D"), pch = c(1, 16))
What can I do to work around this behavior and get multiple 2D graphics to appear?
legend3d() makes a background using legend() after plot(). So it can't make multiple legends. It would be better to use bgplot3d().
open3d()
par3d(windowRect = c(100, 100, 612, 612))
plot3d(x, y, z)
bgplot3d({
par(mar = c(0, 0, 0, 0))
plot(0, 0, type = "n", xlim = 0:1, ylim = 0:1, xaxs = "i",
yaxs = "i", axes = FALSE, bty = "n")
legend(x = 0, y = 0, xjust = 0, yjust = 0, legend = c("2D", "3D"), pch = c(1, 16))
legend(x = 1, y = 0, xjust = 1, yjust = 0, legend = c("2D", "3D"), pch = c(1, 16))
})

Misalignment when using "adj" in title() for an R plot

I want to have my titles be above my points in a pdf plot. It seems R thinks my title is wider than my plot area even though I have my right and left plot margins set to zero.
x <- seq(from = 0.1, to = 0.9, by = 0.1)
xtitle <- c("0.1","0.2","0.3","0.4","0.5","0.6","0.7","0.8","0.9")
pdf("testpdfopts.pdf", width = 16)
par(mar = c(0, 0, 1, 0)) # only need margin at top for title
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
for (i in 1:length(x)) {
title(xtitle[i],adj=x[i],cex.main=1)
}
dev.off()
Thanks in advance for any assistance
I am sort of confused with what you are trying to do. Maybe I should put my comment into complete code:
x <- seq(from = 0.1, to = 0.9, by = 0.1)
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
axis(3, at = 1:9/10)
Is this equivalent to what you aim to achieve?
You can get character labels too:
x <- seq(from = 0.1, to = 0.9, by = 0.1)
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
axis(3, at = 1:9/10, labels = letters[1:9])

Resources