R boxplot; center the axis labels under the tick marks - r

I plotted a dataframe (16700 obs. of 6 variables) using the following code:
labels <–c("X2137_Fe20","X2137_FeXS","vtc1_Fe20",
"vtc1_FeXS","VTC1c_Fe20","VTC1c_FeXS") #labels x axis
[1]col <- c("chartreuse3", "chocolate2", "chartreuse3", "chocolate2",
"chartreuse3", "chocolate2") #colors
#Plot
boxplot(CVtable,
outline = FALSE,
ylim = c(-0.5,70),
main="CV Replicas",
ylab="RSD(%)",
range = 1.5,
width = c(9,9,9,9,9,9),
plot = TRUE,
col = col,
par (mar = c(5,4.5,5,0.5) + 0.1),
par(cex.lab=2),
par(cex.axis=1.7),
notch = TRUE,
labels = labels)
dev.off()
This is the result
I like this box plot, but there are a couple of things I would like to adjust. I need to keep this font size for the x axis labels, but as you can see the labels are too big and part of them is missed. The solution is to rotate them 45 degrees, but I do not manage to find an easy code to insert in my script.
I tried to delete the original axes (axes=FALSE), then setting new ones by
boxplot(CVtable,
outline = FALSE,
ylim = c(0.5,70),
ylab="RSD(%)",
range = 1.5,
width = c(9,9,9,9,9,9),
plot = TRUE,
col = col,
par (mar = c(5,4.5,5,0.5) + 0.1),
notch = TRUE,
par(cex.lab=1.7),
axes=FALSE)
axis(1, at = c(1,2,3,4,5,6), labels = F, tick = 2, line = NA,
pos = -1, outer = F, font = 3, lty = "solid",
lwd = 2, lwd.ticks = 3, col = NULL, col.ticks = NULL,
hadj = NA, padj = 0)
axis(2, at = c(0,10,20,30,40,50,60,70) , labels =
c(0,10,20,30,40,50,60,70), tick = 2, line = NA,
pos = 0.5, outer = FALSE, font = 1, lty = "solid",
lwd = 2, lwd.ticks = 3, col = NULL, col.ticks = NULL,
hadj = NA, padj = 0, par(cex.lab=1.5))
text(x=c(1,2,3,4,5,6),
y=par()$usr[3]-0.1*(par()$usr[4]-par()$usr[3]),
labels=labels, srt=45, adj=1, xpd=TRUE, par(cex.lab=2))
and this is the output: img2
Well, I do not know how to center my labels under the tick marks and how to extend the x axis to the origin of the graph (left) and to the end of the last box (right). Moreover, the argument par(cex.lab=2) to fix the x axis labels font size seems no longer working in that string.
Any good suggestion?
PS: this is my 1st post, if any needed info is missed, please leave a comment and I will reply as soon as I can. Thank you!

I made it myself:
#RSD
boxplot(CVtable[1:6],
outline = FALSE,
ylim = c(0.5,70),
ylab="RSD(%)",
range = 1.5,
width = c(9,9,9,9,9,9),
plot = TRUE,
col = col,
par (mar = c(7,4.5,1,0.5) + 0.1),
notch = TRUE,
par(cex.lab=1.7),
axes=FALSE)
axis(1, at = c(0.5,1,2,3,4,5,6,7), labels = F, tick = 2, line = NA,
pos = -1, outer = F, font = 3, lty = "solid",
lwd = 2, lwd.ticks = 3, col = NULL, col.ticks = NULL,
hadj = NA, padj = 0)
axis(2, at = c(0,10,20,30,40,50,60,70) , labels =
c(0,10,20,30,40,50,60,70), tick = 2, line = NA,
pos = 0.5, outer = FALSE, font = 4, lty = "solid",
lwd = 2, lwd.ticks = 3, col = NULL, col.ticks = NULL,
hadj = NA, padj = 0, par(cex=1.4))
text(x=c(0.7,1.7,2.7,3.7,4.7,5.7),
y=par()$usr[3]-0.14*(par()$usr[4]-par()$usr[3]),
labels=labels, srt=45, adj=0.6, xpd=TRUE, cex=1, font=2)
dev.off()
This is the result:

Related

How can I add axis labels to a plot with custom axes?

I want to add axes labels to the plot generated by the following code. Specifically, I would want an x-axis label that reads "Fibril Diameter (nm)" and a y-axis label that reads "Density". Any idea how I could accomplish this? Thanks!
den1 = density(CDE1$V1)
den2 = density(CDE1$V2)
col1 = hsv(h = 0.65, s = 0.6, v = 0.8, alpha = 0.5)
col2 = hsv(h = 0.85, s = 0.6, v = 0.8, alpha = 0.5)
op = par(mar = c(3, 3, 2, 2))
plot.new( )
plot.window(xlim = c(25,65), ylim = c(0, 0.14))
axis(side = 1, pos = 0, at = seq(from = 25, to = 65, by = 5), col = "gray20",
lwd.ticks = 0.25, cex.axis = 1, col.axis = "gray20", lwd = 1.5)
axis(side = 2, pos = 25, at = seq(from = 0, to = 0.14, by = 0.02), col = "gray20",
las = 2, lwd.ticks = 0.5, cex.axis = 1, col.axis = "gray20", lwd = 1.5)
polygon(den1$x, den1$y, col = col1, border ="black",lwd = 2)
polygon(den2$x, den2$y, col = col2, border ="black",lwd = 2)
text(52, 0.10, labels ="CDET", col =col1, cex = 1.25,font=2)
text(35, 0.03, labels ="SDFT", col =col2, cex = 1.25,font=2)
par(op)
title(main="Gestational Day 100/283")
Here's a picture of what the code generates so far...
Image
You can add your axis labels using title()
title(main="Gestational Day 100/283",
xlab="Fibril Diameter (nm)",
ylab="Density")
or with mtext() which will make it easier for you to fine-tune their exact positioning:
mtext("Fibril Diameter (nm)", side=1, line=2)
mtext("Density", side=2, line=2)
In either case, you will probably need to increase your bottom and left plot margins so that the labels are actually visible, e.g. like this:
op = par(mar=c(4.5, 4.5, 2, 2))

Creating a secondary y-axis in histogram

I have found multiple ways to create a secondary y-axis in plot but I couldn't find a way to create a secondary y-axis in histogram.
Here is a sample code:
a <- sample(90:110, 50, replace=TRUE)
b <- runif(50, min=0, max=1)
hist(a)
lines(b)
b is too small to show in hist(a) so is there any way that I can see both in the histogram?
Technically a solution may be quite an identical to the approach proposed for the plots in this answer. The idea is to use overlapping of two plots as proposed by #r2evans.
It makes sense to use color coding:
# set color rules
col_a <- "red"
col_b <- "darkblue"
col_common <- "black"
Then let's draw the histogram and the plot:
# draw a histogram first
par(mar = c(5, 5, 5, 5) + 0.3)
hist(a, col = col_a, axes = FALSE, xlab = "", ylab = "", main = "")
# add both axes with the labels
axis(side = 1, xlim = seq(along.with = b), col = col_a, col.axis = col_a)
mtext(side = 1, text = "a_value", col = col_a, line = 2.5)
axis(side = 2, col = col_a, col.axis = col_a, ylab = "")
mtext(side = 2, text = "a_Frequency", col = col_a, line = 2.5)
# ... and add an overlaying plot
par(new=TRUE)
plot(b, ylim = c(0, 1), axes = FALSE, col = col_b, type = "l", xlab = "", ylab = "")
points(b, col = col_b, pch = 20, xlab = "", ylab = "")
axis(side = 3, xlim = seq(along.with = b), col = col_b, col.axis = col_b)
mtext(side = 3, text = "b_index", col = col_b, line = 2.5)
axis(side = 4, ylim = c(0, 1), col = col_b, col.axis = col_b)
mtext(side = 4, text = "b_value", col = col_b, line = 2.5)
box(col = col_common)

R Shiny plot won't render

Hi can anyone see what is the problem with the code below?
output$zscore_chart <- renderPlot({
xvals <- 2:186
req(input$countrySelectZScore)
idx_country = which(input$countrySelectZScore == esiCountries)
max_comp_z <- max(esiData_DF[idx_country, 2:186], na.rm = TRUE)
overall_max_z <- max(max_comp_z, na.rm = TRUE)
foo = ts(esiData_DF[idx_country, 2:186], frequency = 12, start = 2001)
dates = seq(as.Date("2001-01-01"), by = "month", along = foo)
plot(x = 2:186, y = esiData_DF[idx_country, 2:186], type = "l",
xlab = "", ylab = "", col = "grey20", ylim = c(-2, overall_max_z),
lwd=3,las=2)
mtext("Quarterly percentage changes", side = 3, adj = 0, line = 0.1,
cex = 1, font = 0.5)
axis(1, at = xvals, label = dates, cex.axis = 1, las = 2)
mtext("Economic Sentiment Indicators", side = 3, adj = 0,
line = 1.2, cex = 2, font = 2)
legend(
"bottom",
lty = c(1,1),
lwd = c(3,3),
col = c("grey20", "green2"),
legend = c("Economic Sentiment Indicator", "GDP growth"),
bty = "n",
xjust = 0.5,
yjust = 0.5,
horiz = TRUE
)
}, height = 525)
esiData_DF is the DF used to index and plot the correct data. The dataframe has the country names down the left hand side with the dates, monthly across the top. I need the plot to render but it wont when I run the app. Any ideas?
The data continues to the right, up to May 2017 monthly.

Align plot with barplot in R

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)

Plotting mean in R at specific X-axis

In R, is there a way to add means to a plot at specific x-axis. For example, I want to do something like:
plot(1, 1, xlim = c(0, 6.5), ylim = c(0,300), type = 'n', xlab = '', ylab = '', xaxt = 'n') #xaxs="i",yaxs="i")
boxplot(dataset,at = 0.5, add = T, range = 6,yaxt = 'n')
points(mean(dataset), at = 0.5, add = T)
I get a message saying "at" and "add" are 'not a graphical parameter'. Is there a workaround?
So I am using RStudio. There are six different values (data_a, data_b, data_c, data_d, data_e, and data_f) each with 11 numbers. My current code looks like follows:
par(xpd = FALSE)
par(mar=c(8,4.5,2,1))
plot(1, 1, xlim = c(0, 6.5), ylim = c(0,300), type = 'n', xlab = '', ylab = '', xaxt = 'n') #xaxs="i",yaxs="i")
boxplot(data_a,at = 0.5, add = T, range = 6,yaxt = 'n')
boxplot(data_b,at = 1.5, add = T, range = 6,yaxt = 'n')
boxplot(data_c,at = 2.5, add = T, range = 6,yaxt = 'n')
boxplot(data_d,at = 4, add = T, range = 6,yaxt = 'n')
boxplot(data_e,at = 5, add = T, range = 6,yaxt = 'n')
boxplot(data_f,at = 6, add = T, range = 6,yaxt = 'n')
axis(2, at = 150, pos = -0.65, tck = 0, labels = 'X axis label',cex.axis=1.1)
axis(1, at = c(0.5,1.5,2.5,4,5,6),labels=c('','','','','',''))
axis(1, at = c(1.5,5),pos= -25,labels=c('label 1','labe 2'),tick=FALSE)
axis(1, at = c(3.25),labels=c(''),tck=-0.15)
axis(1, at = c(3.25),pos = -50,labels=c('Y axis label'),tick=FALSE)
abline(v=3.25)
par(xpd = NA)
text(0.5,-30, expression("a))
text(1.5,-30, expression("b"))
text(2.5,-30,"c")
text(4,-30, expression(d))
text(5,-30, expression("e"))
text(6,-30,"f")
Now I want to be able to add mean.
You can try this to get the desired plot (with randomly generated data_a, data_b etc.):
par(xpd = FALSE)
par(mar=c(8,4.5,2,1))
plot(1, 1, xlim = c(0, 6.5), ylim = c(0,300), type = 'n', xlab = '', ylab = '', xaxt = 'n') #xaxs="i",yaxs="i")
data_a <- runif(11, 0, 300)
data_b <- runif(11, 0, 300)
data_c <- runif(11, 0, 300)
data_d <- runif(11, 0, 300)
data_e <- runif(11, 0, 300)
data_f <- runif(11, 0, 300)
boxplot(data_a,at = 0.5, add = T, range = 6,yaxt = 'n')
boxplot(data_b,at = 1.5, add = T, range = 6,yaxt = 'n')
boxplot(data_c,at = 2.5, add = T, range = 6,yaxt = 'n')
boxplot(data_d,at = 4, add = T, range = 6,yaxt = 'n')
boxplot(data_e,at = 5, add = T, range = 6,yaxt = 'n')
boxplot(data_f,at = 6, add = T, range = 6,yaxt = 'n')
axis(2, at = 150, pos = -0.65, tck = 0, labels = 'X axis label',cex.axis=1.1)
axis(1, at = c(0.5,1.5,2.5,4,5,6),labels=c('','','','','',''))
axis(1, at = c(1.5,5),pos= -25,labels=c('label 1','label 2'),tick=FALSE)
axis(1, at = c(3.25),labels=c(''),tck=-0.15)
axis(1, at = c(3.25),pos = -50,labels=c('Y axis label'),tick=FALSE)
abline(v=3.25)
par(xpd = NA)
text(0.5,-30, expression("a"))
text(1.5,-30, expression("b"))
text(2.5,-30,"c")
text(4,-30, expression("d"))
text(5,-30, expression("e"))
text(6,-30,"f")
points(c(0.5,1.5,2.5,4,5,6), c(mean(data_a), mean(data_b), mean(data_c), mean(data_d), mean(data_e), mean(data_f)), pch = 22, col = "darkgrey", lwd = 7)
With boxplots, the location of the plots on the x axis are at the units (1, 2, 3, etc.). You can check this using the function locator().
Here is an example to add means as a red circle to a boxplot using the iris dataset:
boxplot(Sepal.Length ~ Species, data = iris)
points(seq_along(levels(iris$Species)), with(iris, tapply(Sepal.Length, Species, mean)), col = "red")

Resources