I want to display two plots with the same x-values above each other. But the plots don't align.
How can I align them?
Code:
dat <- data.frame(d = LETTERS[1:5], c = c(39, 371, 389, 378, 790), r = c(39,
332, 18, -11, 412))
par(mfrow=c(2,1))
plot(dat$c, type = "s", ylim = c(0, max(dat$c)), xlab = "", ylab = "", axes = FALSE, col = "#4572a7", lwd = 2)
axis(1, at = c(1:length(dat$c)), labels = dat$d, lty = 0)
axis(2, lty = 0, las = 1)
barplot(dat$r, names.arg = dat$d, col = "#008000", border = NA, axes = FALSE)
axis(2, lty = 0, las = 1)
abline(h = 0, col = "#bbbbbb")
We need to get the x-coordinates of the center of each bar and use those coordinates as the x-values of the first plot. We also need to set the same xlim values for each plot:
# Get x coordinates of center of each bar
pr = barplot(dat$r, names.arg = dat$d, col = "#008000", border = NA, axes = FALSE,
plot=FALSE)
par(mfrow=c(2,1))
# Apply the x coordinates we just calculated to both graphs and give both
# graphs the same xlim values
plot(pr, dat$c, type = "s", ylim = c(0, max(dat$c)), xlab = "", ylab = "", axes = FALSE,
col = "#4572a7", lwd = 2, xlim=range(pr) + c(-0.5,0.5))
axis(1, at = pr, labels = dat$d, lty = 0)
axis(2, lty = 0, las = 1)
barplot(dat$r, names.arg = dat$d, col = "#008000", border = NA, axes = FALSE,
xlim=range(pr) + c(-0.5,0.5))
axis(2, lty = 0, las = 1)
Related
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)
Any tips to remove the zero labels in between the histogram bars?
hist(links$Survey_Duration, breaks = seq(0,50,5), main = "Survey Duration",
labels = TRUE, border = "black",
xlab = "Survey", ylim = c(0, 15), col = "gray", las = 1, xaxt='n')
axis(side=1, at=seq(0,50,5), labels=seq(0,50,5))
abline(v = mean(links$Survey_Duration), col = "royalblue", lwd = 1.5)
abline(v = median(links$Survey_Duration), col = "red", lwd = 1.5)
legend(x = "topright", c("Mean", "Median"), col = c("royalblue","red"),
lwd = c(1.5,1.5))
How about this?
# modify data so there's zero in one of the bins
mtcars$mpg <- ifelse(mtcars$mpg >= 25 & mtcars$mpg <= 30, NA, mtcars$mpg)
# save plot parameters
h <- hist(mtcars$mpg, plot = FALSE)
# produce plot
plot(h, ylim = c(0, 14))
# add labels manually, recoding zeros to nothing
text(h$mids, h$counts + 1, ifelse(h$counts == 0, "", h$counts))
A slightly different answer using the labeling in hist instead of adding text afterwards.
You do not provide your data, so I will use some data that is handy to illustrate.
The labels argument can specify the individual labels
H1 = hist(iris$Sepal.Length, breaks = 3:8, plot=FALSE)
BarLabels = H1$counts
BarLabels[BarLabels == 0] = ""
hist(iris$Sepal.Length, breaks = 3:8, labels = BarLabels)
Thanks #Daniel Anderson, it Ok now (Thumbs Up)
links$Survey_Duration <- ifelse(links$Survey_Duration > 15 &
links$Survey_Duration <= 25,
NA,
links$Survey_Duration)
h <- hist(links$Survey_Duration, breaks = seq(0,50,5), plot = FALSE)
plot(h, ylim = c(0, 14), main = "Survey Duration", xlab = "Time", col = "gray", las = 1)
text(h$mids, h$counts + 1, ifelse(h$counts == 0, "", h$counts))
axis(side=1, at=seq(0,50,5), labels=seq(0,50,5))
abline(v = mean(links$Survey_Duration), col = "royalblue", lwd = 1.5)
abline(v = median(links$Survey_Duration), col = "red", lwd = 1.5)
legend(x = "topright",
c("Mean", "Median"),
col = c("royalblue","red"),
lwd = c(1.5,1.5))
Consider the following vector:
q1 <- c(1000000.0, 908364.8, 876009.1, 847892.8, 824808.3, 805416.2, 785266.2, 770997.1, 753908.6, 744599.9, 706777.6, 674659.9, 634654.4, 601440.4, 568259.7, 535361.3, 493679.9, 465526.5, 429766.6, 395244.7, 361483.2, 332136.6, 308574.5, 285500.6, 262166.2 ,237989.0 , 210766.1, 188578.1, 166762.3 , 140399.8 ,114865.5)
Here is the plot:
dev.new(width=10, height=5)
par(xaxs='i',yaxs='i')
plot(q1, type = "l", lty = 1, lwd = 2, col = "green", xaxt = 'n', xlim = c(0,30), bty = "l")
x.ticks = seq(from = 0, to = 30, by = 5)
axis(1, at = x.ticks+1, labels=paste("Year", x.ticks, sep=" "))
For some reason, my x-axis and y-axis are not meeting at (0,0)! I tried fixing this by using par(xaxs='i',yaxs='i'), but it doesn't do the trick in this case?
Any ideas? Thanks!
If you do not specify ylim, R will fit the plot area to the data, not extend the plot to the origin. This will fix it:
plot(q1, type = "l", lty = 1, lwd = 2, col = "green", xaxt = 'n',
xlim = c(0,30), ylim = c(0, max(q1, na.rm = TRUE)), bty = "l")
I wrote the ylim to look for the maximum in q1. You can change it to a fixed value.
Here is the full code I ran to make it work:
q1 <- c(1000000.0, 908364.8, 876009.1, 847892.8, 824808.3, 805416.2,
785266.2, 770997.1, 753908.6, 744599.9, 706777.6, 674659.9,
634654.4, 601440.4, 568259.7, 535361.3, 493679.9, 465526.5,
429766.6, 395244.7, 361483.2, 332136.6, 308574.5, 285500.6,
262166.2 ,237989.0 , 210766.1, 188578.1, 166762.3 , 140399.8 ,114865.5)
dev.new(width=10, height=5)
par(xaxs='i',yaxs='i')
plot(q1, type = "l", lty = 1, lwd = 2, col = "green",
xaxt = 'n', xlim = c(1,30), ylim = c(0, max(q1)), bty = "l")
x.ticks = seq(from = 0, to = 30, by = 5)
axis(1, at = x.ticks + 1, labels=paste("Year", x.ticks, sep=" "))
Does anyone know how to extract the 'y' off the y-axis while preserving the variable names in the following plot:
par(mar = c(5,7,4,2) +.01)
matrix <- matrix(rnorm(100) ,ncol = 2, nrow =6)
y <- 1:6
par(mar = c(5,7,4,2) +.01)
plot(matrix[,1], y, cex = .8, pch = 20, xlab = "Standardized Mean Differences", col = "darkblue", main = "Balance Assessment", yaxt = "n")
points(matrix[,2], y, cex = .8, pch = 20, col ="cyan")
abline(v = 0, col = "gray50", lty =2)
text(y =1:6, par("usr")[1], labels = c("Var1", "Var2", "Var3", "Var4", "Var5", "Var6"), pos = 2, xpd = TRUE, srt = 0, cex = .8, font = 1, col = "blue")
It's minor, but it's driving me crazy. Thanks!
Just set ylab='' to remove it.
I am trying to design a fairly customized plot in R.
One thing I want to do is add tick marks that are different from the labels - that is, only every 5th tick mark will be labeled. I didn't see an easy way to do this, so I did this:
plot(x = Freq_, y = Mean_ipsi,
pch = 20,
ylim = c(-0.5, .9),
col = 1 + (ProbF < .05) + (ProbF < .01),
xaxt = 'n',
xlab = "Frequency (MHz)", ylab = "z-in minus z-out",
main = "Temporal, Engle 1, Epi, subjectwise",
yaxt = 'n')
mtext(text = seq(1.56, 35.1, by = 1.95),
side = 1, at = seq(1.56, 35.1, by = 1.95), cex = .5,line = 0.25)
axis(1, at = Freq_, tick = TRUE, labels = NA)
and it worked just as I wanted.
But when I changed some of the code preceding mtext I got unexpected results
plot(x = Freq_, y = Mean_ipsi,
pch = 20,
ylim = c(-0.5, .9),
col = "red",
xlab = "Frequency (MHz)", ylab = "z-in minus z-out",
main = "Temporal, Engle 1, Epi, subjectwise
\n p values for difference between ipsi and contra",
yaxt = 'n', type = 'o')
mtext(text = seq(1.56, 35.1, by = 1.95),
side = 1, at = seq(1.56, 35.1, by = 1.95),
cex = .5,line = 0.25)
axis(1, at = Freq_, tick = TRUE, labels = NA)
Now, in addition to the x-axis being labeled with every numbers 1.56, 3.51, etc. I get large numbers (cex = 1, I think) at 5, 10 and so on. I don't want these.
I have no idea what is happening here.
You're missing xaxt="n" in your second version.
Freq_ <- seq(1.56, 35.1, by = 1.95)
Mean_ipsi <- (0.01 * Freq_)
ProbF <- 0.0
#First Version
plot(x = Freq_, y = Mean_ipsi,
pch = 20,
ylim = c(-0.5, .9),
col = 1 + (ProbF < .05) + (ProbF < .01),
xaxt = 'n',
xlab = "Frequency (MHz)", ylab = "z-in minus z-out",
main = "Temporal, Engle 1, Epi, subjectwise",
yaxt = 'n')
mtext(text = seq(1.56, 35.1, by = 1.95),
side = 1, at = seq(1.56, 35.1, by = 1.95), cex = .5,line = 0.25)
axis(1, at = Freq_, tick = TRUE, labels = NA)
#=============================================
#Second Version
plot(x = Freq_, y = Mean_ipsi,
pch = 20,
ylim = c(-0.5, .9),
col = "red",
xlab = "Frequency (MHz)", ylab = "z-in minus z-out",
main = "Temporal, Engle 1, Epi, subjectwise
\n p values for difference between ipsi and contra",
yaxt = 'n', type = 'o') ##### <----- add xaxt="n" here #####
mtext(text = seq(1.56, 35.1, by = 1.95),
side = 1, at = seq(1.56, 35.1, by = 1.95),
cex = .5,line = 0.25)
axis(1, at = Freq_, tick = TRUE, labels = NA)