I am trying to plot a tornado graph for sensitivity analysis purposes. This is what I have so far.
OP <- par(mar = c(7,7,7,7))
data <- matrix(c(-0.10,0.15,-0.01,0.01,-0.03,0.08,-0.1,0.07), ncol = 4)
# Amount of Change in Variables
rownames(data) <- c('+25%','-25%')
# Names of Variables
colnames(data) <- c('Variable 1', 'Variable 2', 'Variable 3','Variable 4')
# For Plotting % on X-Axis
x <- seq(-0.30,0.30, length=13)
SEQUENTIAL <- RColorBrewer::brewer.pal(4, "YlOrRd")
barplot(data[1,], main="Tornado Graph", horiz = T, las=1, xlim = c(-0.30,0.30), xaxt='n', ylab = '', col=SEQUENTIAL)
barplot(data[2,], horiz = T, las=1, xlim = c(-0.30,0.30), xaxt='n', ylab = '', col=SEQUENTIAL, add = TRUE)
# Add x-axis
axis(1, at=x, labels=paste0(x * 100," %"), las=TRUE)
par(OP)
The bars of the tornado graph are not sorted like in a proper graph. How do I sort them in decreasing length?
Thanks
Just put the columns in order for plotting. Replace your two barplot statements with
ORD = order(data[2,] - data[1,])
barplot(data[1,ORD], main="Tornado Graph", horiz = T, las=1,
xlim = c(-0.30,0.30), xaxt='n', ylab = '', col=SEQUENTIAL)
barplot(data[2,ORD], horiz = T, las=1, xlim = c(-0.30,0.30), xaxt='n',
ylab = '', col=SEQUENTIAL, add = TRUE)
Related
I'm making stacked boxplots and plots on top of one another using R's layout command in base graphics.
The graphs look great, except that y-axis labels from different plots overlap (highlighted in red circle):
Similar questions are here online, but none of them use layout.
I don't want to expand the space between the plots, I don't think this will look good.
How
I've tried reducing the font size, but the labels still go outside the plot area.
How can I set R's boxplot and plot so that the tick labels do not go above or below the red line, i.e. the max/min y-value, in the image above?
Some example code
legend_space <- -0.26
right <- 10.5
bottom <- 0
left <- 5
top <- 0
cex_main = 1
setEPS()
postscript('figure.eps')
g1 <- c()
g2 <- c()
p <- c()
percent <- c()
sum_p <- c()
sum_percent <- c()
g1_means <- c()
g2_means <- c()
xaxis <- c()
sum_p[1] <- 0.0430904
xaxis[1] <- 2984116
p[1] <- 0.0430904
percent[1] <- -65.1758
sum_percent[1] <- -65.1758
g1[1] <- list(c(47.058824,100.000000,100.000000))
g1_means[1] <- 84.482759
g2[1] <- list(c(13.750000,4.123711,96.000000))
g2_means[1] <- 19.306931
sum_p[2] <- 0.0443229
xaxis[2] <- 2984148
p[2] <- 0.0587825
percent[2] <- -73.8956
sum_percent[2] <- -69.332
g1[2] <- list(c(94.285714,94.736842,100.000000))
g1_means[2] <- 95.145631
g2[2] <- list(c(10.588235,0.000000,92.592593))
g2_means[2] <- 21.250000
sum_p[3] <- 0.0444647
xaxis[3] <- 2984157
p[3] <- 0.124606
percent[3] <- -40.2577
sum_percent[3] <- -60.3056
g1[3] <- list(c(76.315789,94.736842,64.705882))
g1_means[3] <- 83.928571
g2[3] <- list(c(63.529412,0.000000,60.000000))
g2_means[3] <- 43.670886
sum_p[4] <- 0.0393696
xaxis[4] <- 2984168
p[4] <- 0.0310268
percent[4] <- -38.4133
sum_percent[4] <- -54.7893
g1[4] <- list(c(59.459459,57.894737,100.000000))
g1_means[4] <- 64.864865
g2[4] <- list(c(35.294118,6.250000,36.363636))
g2_means[4] <- 26.451613
sum_p[5] <- 0.0304293
xaxis[5] <- 2984175
p[5] <- 0.0344261
percent[5] <- -50.5157
sum_percent[5] <- -54.0582
g1[5] <- list(c(62.500000,94.736842,100.000000))
g1_means[5] <- 85.849057
g2[5] <- list(c(52.873563,6.250000,26.666667))
g2_means[5] <- 35.333333
layout(matrix(c(0,0,1,1,2,2,3,3,4,4), nrow = 5, byrow = TRUE), heights = c(0.2,1,1,1,1.4))
par(mar = c(bottom, left, top, right))
boxplot(g1, xaxt = 'n', range = 0, ylab = '%', ylim = c(0,100), col = 'white', cex.lab=1.5, cex.axis=cex_main, cex.main=cex_main, cex.sub=1.5, xlim = c(0.5,length(g1)+0.5))
title('title', outer = TRUE, line = -1.5)
lines(g1_means, col='dark green', lwd = 3)
par(xpd=TRUE)
legend('topright',inset = c(legend_space,0), c('Control', 'Weighted Mean'), col = c('black','dark green'), lwd = c(1,3))
boxplot(g2, xaxt = 'n', range = 0, main = NULL, ylim = c(0,100), ylab = '%', col = 'gray', cex.lab=1.5, cex.axis=cex_main, cex.main=cex_main, cex.sub=1.5, xlim = c(0.5,length(g2)+0.5))
lines(g2_means, col='dark green', lwd = 3)
par(xpd=TRUE)
legend('topright',inset = c(legend_space,0),c('Case', 'Weighted Mean'), col = c('black','dark green'), lwd = c(1,3))
par(mar = c(bottom, left, top, right))#'mar’ A numerical vector of the form 'c(bottom, left, top, right)’
plot(p, xaxt='n', ylab = 'P', type = 'l', lty = 1, lwd = 3, cex.lab=1.5, cex.axis=1, cex.main=cex_main, cex.sub=1.5, , log = 'y', xlim = c(0.5,length(p)+0.5), ylim = c(min(p,sum_p), max(p, sum_p)))
points(sum_p, xaxt='n', ylab = 'P', type = 'l', col = 'blue', lty = 2, lwd = 3)
legend('topright', inset=c(legend_space,0), c('CpG P', 'Moving P Mean'), col = c('black','blue'), lwd=c(3,3), lty=c(1,2))
par(mar = c(bottom+5, left, top, right))#'mar’ A numerical vector of the form 'c(bottom, left, top, right)’
plot(percent, xaxt='n', ylab = '% Diff.', xlab = 'CpG', type = 'l', lty = 1, lwd = 3, cex.lab=1.5, cex.axis=1, cex.main=cex_main, cex.sub=1.5, xlim = c(0.5,length(percent)+0.5), ylim = c(min(percent, sum_percent), max(percent, sum_percent)))
points(sum_percent, xaxt='n', xlab = 'CpG', type = 'l', col = 'blue', lty = 2, lwd = 3)
par(xpd=TRUE)
legend('topright', inset=c(legend_space,0), c('Percent', 'Moving Mean %'), col = c('black','blue'), lwd=c(3,3), lty=c(1,2))
axis( 1, at=1:length(xaxis), xaxis)
dev.off()
thanks to #count, the solution is simply to use
las=2 in par settings. las=2 sets the labels to be read vertically.
I want to plot my points on a graph and then show the density distribution on the x-axis and on the y-axis at the same time.
I'm able to do it on the x axis but not on the y axis.
par(mfrow=c(1,1))
plot(rnorm(100))
par(new=TRUE)
plot(density(rnorm(100,10,123)), ann = FALSE, xlab = "", ylab ="",xaxt='n', yaxt='n')
par(new=TRUE)
plot(density(rnorm(100, 10,12)), col = "red", ann = FALSE, xlab = "", ylab ="",xaxt='n', yaxt='n')
There is no reason you can't.
set.seed(0)
d1 <- density(rnorm(100, 10, 123))
d2 <- density(rnorm(100, 10, 130))
## shared x, y, range / limit
xlim <- c(min(d1$x[1], d2$x[1]), max(d1$x[512], d2$x[512])) ## default: n = 512
ylim <- c(0, max(d1$y, d2$y))
## conventional plot
plot(d1$x, d1$y, type = "l", xlim = xlim, ylim = ylim)
lines(d2$x, d2$y, col = 2)
## rotated plot
plot(d1$y, d1$x, type = "l", xlim = ylim, ylim = xlim)
lines(d2$y, d2$x, col = 2)
Remarks:
never use par(new = TRUE); set xlim and ylim yourself;
customize the plot with title, axis display yourself.
I am trying to produce a plot with histogram and scatter plot in just one plot using a secondary axis. In detail, here is an example data:
#generate example data
set.seed(1)
a <- rnorm(200,mean=500,sd=35)
data <- data.frame(a = a,
b = rnorm(200, mean=10, sd=2),
c = c(rep(1,100), rep(0,100)))
# produce a histogram of data$a
hist(a, prob=TRUE, col="grey")
#add a density line
lines(density(a), col="blue", lwd=2)
#scatter plot
plot(data$a,data$b,col=ifelse(data$c==1,"red","black"))
What I want to do is to combine the histogram and scatter plot together. This implies my x-axis will be data$a, my primary y-axis is the frequency/density for the histogram and my secondary y-axis is data$b.
Maybe something like this...
# produce a histogram of data$a
hist(a, prob=TRUE, col="grey")
#add a density line
lines(density(a), col="blue", lwd=2)
par(new = TRUE)
#scatter plot
plot(data$a,data$b,col=ifelse(data$c==1,"red","black"),
axes = FALSE, ylab = "", xlab = "")
axis(side = 4, at = seq(4, 14, by = 2))
There's a good blog on this here http://www.r-bloggers.com/r-single-plot-with-two-different-y-axes/.
Basically, as the blog describes you need to do:
par(new = TRUE)
plot(data$a,data$b,col=ifelse(data$c==1,"red","black"), axes = F, xlab = NA, ylab = NA)
axis(side = 4)
how to
Combine a bar chart and line in single plot in R (from different data sources)?
Say I have two data sources as:
barData<-c(0.1,0.2,0.3,0.4) #In percentage
lineData<-c(100,22,534,52,900)
Note that they may not be in the same scale.
Can I plot both barData and LineData in one plot and make them good looking ?
I cant use ggplot in this case so this is not a duplicated question..
Something like the following:
Maybe this helps as a starting point:
par(mar = rep(4, 4))
barData<-c(0.1,0.2,0.3,0.4) * 100
y <- lineData<-c(100,22,534,900);
x <- barplot(barData,
axes = FALSE,
col = "blue",
xlab = "",
ylab = "",
ylim = c(0, 100) )[, 1]
axis(1, at = x, labels = c("Julia", "Pat", "Max", "Norman"))
ats <- c(seq(0, 100, 15), 100); axis(4, at = ats, labels = paste0(ats, "%"), las = 2)
axis(3, at = x, labels = NA)
par(new = TRUE)
plot(x = x, y = y, type = "b", col = "red", axes = FALSE, xlab = "", ylab = "")
axis(2, at = c(pretty(lineData), max(lineData)), las = 2)
mtext(text="Lines of code by Programmer", side = 3, line = 1)
box()
I want to remove labels and axis from X axis, however adding new ticks.
plot(1:10, ylab = "")
at1 <- seq(1, 10, 0.1)
axis(side = 1, at = at1, labels = FALSE)
I could not get rid of y labels.
see ?par You need the xaxt argument
plot(1:10, ylab = "", xaxt='n')
I am not certain what you want, but this removes the x label and uses the tick marks you are generating with at1:
plot(1:10, ylab = "", xlab="")
at1 <- seq(1, 10, 0.1)
axis(side =1, at1, labels = F)
I took the suggestion by GSee to remove the y tick marks if you also want to do that.
plot(1:10, xlab = "", ylab = "", yaxt='n')
at1 <- seq(1, 10, 0.1)
axis(side =1, at1, labels = F)