How to reorder bars of a tornado graph in R? - r

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

R base graphics: overlapping axis tick labels from different plots with layout

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.

Can I rotate a graph and plot it on the y axis?

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.

combine histogram with scatter plot in R

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)

Put one line chart and bar chart in one plot in R (Not ggplot)?

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()

Suppress ticks in plot in r

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)

Resources