I have code producing the below pasted plot
x <- c(2, 3, 4)
y <- c(2.5, 4.1, 5.5)
plot(x, y, type = "o", xlim = c(1, 5), ylim = c(2, 6), axes = FALSE, bty = "n")
axis(side = 1, at = seq(1, 5, 1))
axis(side = 2, at = seq(2, 6, 1), las = 2)
I would like to have neither ticks nor labels at position 1 and 5, but the axis should still be drawn. This is what I am looking for:
When using labels = c("", 2, 3, 4, "") ticks are drawn. When using tick = FALSE, I get no axis. Does anybody have a solution for this?
You just need to draw the line manually. Using the line2user function in this answer:
x <- c(2, 3, 4)
y <- c(2.5, 4.1, 5.5)
plot(x, y, type = "o", xlim = c(1, 5), ylim = c(2, 6), axes = FALSE, bty = "n")
axis(side = 1, at = 2:4)
lines(x = c(1, 5), y = rep(line2user(0, side = 1), 2), xpd = TRUE)
axis(side = 2, at = seq(2, 6, 1), las = 2)
Note, the line2user function just gives the position of the lines in the user coordinate system. You need the xpd = TRUE to draw outside the plotting region.
Related
I have two matrices of same size.
x1 = matrix(data = c(1, 3, 4, 5, 5, 3, 3, 1), nrow = 4, ncol= 2, byrow = TRUE)
x2 = matrix(data = c(-1, -4, 3, 7, -2, 2, 4, -1), nrow = 4, ncol= 2, byrow = TRUE)
I want to plot the both on the same scatter plot, however, x should contain all 'x' values from both x1 and x2, and y also should contain all 'y' values from both matrices.
Matplot doesn't seem to do the work, since it only compares the columns.
How can I do this (if possible without using any packages)?
You can use plot
plot(x1, xlim = c(-3, 6), ylim = c(-5, 7), col = "red", xlab = "X", ylab = "Y")
par(new=TRUE)
plot(x2, xlim = c(-3, 6), ylim = c(-5, 7), col = "blue", xlab = "", ylab = "")
We can use pairs
pairs(cbind(c(x1), c(x2)))
Or just remove the dim attributes in 'x1', 'x2' with c to convert to vector and use plot
plot(c(x1), c(x2))
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.
How does the fillOddEven parameter work in the polygon function in R? I have tried a couple of examples but can't spot a change:
layout(matrix(1:2,ncol=2))
x <- c(1:9, 8:1)
y <- c(1, 2*(5:3), 2, -1, 17, 9, 8, 2:9)
plot(1:10)
polygon(x, y, col = "orange", lty = 2, lwd = 2, border = "red",fillOddEven = T)
plot(1:10)
polygon(x, y, col = "orange", lty = 2, lwd = 2, border = "red",fillOddEven = F)
I'm plotting a series of data, using the following code:
x <- 2008:2016
y <- c(757221, 768845, 672496, 672387, 682506, 657828, 630625, 639334, 1178876)
par(mar = c(0, 0, 0, 0))
par(oma = c(2.5, 0.5, 0.5, 0.5))
plot(x, y, bty = "n", yaxt = "n", xlab = "", ylab = "", pch = 18, col = "#5889C1", xaxp = c(2008, 2016, 8), cex = 1.5)
yl <- format(y, big.mark = ".", decimal.mark = ",")
poslab <- c(1, 3, 1, 1, 3, 3, 1, 1, 3)
text(x, y, labels = yl, pos = poslab, cex = 0.9)
lines(x, y, col = "#5889C1", lwd = 3)
But some labels, in the borders of the screen are not entirely shown (unfortunately, I couldn’t upload an image, but will continue trying): anyone who rerun this code will see the first label cut at left, the seventh cut at bottom and the ninth (last) cut at top.
So, I wish to know how can I reset the margin parameters to avoid it and allow all labels to be entirely shown.
I have big data like the following but this just little sample.
pos <- c(1, 3, 5, 8, 10, 12)
start <- c(1,3, 6, 7, 10, 11)
end <- c(5, 6, 9, 9, 13, 12)
Qunatative variable Pos will be Y axis and X axis will be anthor X variable (quantitative). The horizontal bar length for each Pos value is defined by start and end point. For example,line for 1 will start from 1 and end at 3 in x axis.
The following is rough sketch of desired the figure output.
In base R...
plot(pos, type = 'n', xlim = range(c(start, end)), ylim = c(13,0))
grid()
segments(start, pos, end, pos)
To get it more exactly like your figure...
r <- par('usr')
plot(pos, type = 'n', xlim = range(c(start, end)), ylim = c(13.5,0.5), xlab = '',
xaxt = 'n', yaxt = 'n', panel.first = rect(r[1], r[3], r[2], r[4], col = 'goldenrod'))
# abline(h = 1:13, col = 'white')
# abline(v = 1:13, col = 'white')
grid(lty = 1, col = 'white')
axis(1, 1:13, 1:13, cex.axis = 0.8)
axis(2, 1:13, 1:13, las = 1, cex.axis = 0.8)
segments(start, pos + 0.5, end, pos + 0.5, lwd = 2)
Use package ggplot2 with geom_segment to draw the lines.
Start by combining your data into a data.frame, since this the required data structure for ggplot:
dat <- data.frame(
pos = c(1, 3, 5, 8, 10, 12),
start = c(1,3, 6, 7, 10, 11),
end = c(5, 6, 9, 9, 13, 12)
)
Create the plot:
library(ggplot2)
ggplot(dat) +
geom_segment(aes(x=start, y=pos, xend=end, yend=pos), color="blue", size=3) +
scale_y_reverse()