adding grouping lines to a barplot in R - r

I created a barplot using the follow code:
#create function for plotting error bars
errb <- function (x, y, ebl, ebu = ebl, length = 0.08, ...){
arrows(x, y + ebu, x, y - ebl, angle = 90, code = 3,
length = length, ...)
}
#generate plot data
means <- c(0.976,0.664, 1.12, 1.22)
errs <- c(0.16, 0.17, 0.16, 0.16)
#plot labels
names <- c('+NaCl', '+NaCl',expression(paste('+NaNO'[3])),expression(paste('+H'[2]*'O')))
#plot
plot1<-barplot(means, beside=T,border=NA,
ylim=c(0,1.6),
names.arg=names)
errb(plot1,means,ebl=errs,ebu=errs)
box(bty="L")
It looks like this:
I'd like to add some labels in the top white space of the figure, to indicate whether or not the treatment E was present. The first bar is (-E) and bars 2-4 are (+E). I'd like the outcome to look like this drawing:
How can I go about doing this in base R?

You just need to use text() and arrows(). Consider:
text(x=0.7, y=1.5, labels="(-E)", adj=c(.5,.5))
text(x=3.1, y=1.5, labels="(+E)", adj=c(.5,.5))
arrows(x0=1.4, x1=2.9, y0=1.5, code=1, angle=90, length=.1)
arrows(x0=3.3, x1=4.8, y0=1.5, code=2, angle=90, length=.1)

Related

Scatterplot numerical y against two x groups

From my data, I created the following vectors:
ratio_automatic <- c(2.031, 2.24, 2.00, 0.46, 2.75, 0.86, 2.69, 0.44)
ratio_manual <- c(1.02, 2.40, 1.53, 0.50, 1.38, 0.70, 1.69, 0.54)
method <- rep(c("Manual", "Automatic"), each = 8)
to create the following dataframe:
df <- data.frame(method, c(ratio_automatic, ratio_manual))
names(df) <- c("method", "ratio")
So I think that is then called narrow data?
In summary: there are 16 observations to two variables.
I want to plot the data in a scatterplot, so you can see the ratio datapoints grouped by category (either 'manual' or 'automatic').
When I run the following code:
plot(1:nrow(df), df$ratio, xaxt="n", xlab="Method", ylab="Ratio", pch=19)
axis(1, at=1:16, labels=df$method)
I get the following graph:
This is not what I want, as I want on the x-axis just 'automatic' and 'manual' and then the corresponding points above that, not each point separate like now.
is there a way to fix this?
(I'm still very new to R, so I'm sorry if this is an obvious question.)
If you want "Automatic" and "Manual" to appear only once on the x-axis, then you shouldn't make a scatterplot. Scatterplots assumes that both your x- and y-axes are continuous. Consider making a boxplot and overlaying with jittered points, similar to what you would find in a scatterplot.
# make a boxplot
boxplot(df$ratio ~ df$method, col = "white")
# add some points
stripchart(df$ratio ~ df$method,
method = "jitter",
pch = 19,
vertical = TRUE,
add = TRUE)
Maybe you want something like this where you start with an empty plot and then plot on the 1 and 2 of your factor methods and use points to add the data like this which results in a jitter plot ( you can adjust the positions of your labels in axis):
plot(1, type="n", xlim=c(0, 3), xaxt="n", ylim = c(0, 3), xlab="Method", ylab="Ratio", pch=19)
axis(1, at=1:2, labels=unique(df$method))
points(factor(df$method), df$ratio, xaxt="n", xlab="Method", ylab="Ratio", pch=19)
Output:

Log Y axis in barplot with values smaller than 1 and including plot lines with negative values

I have plotted a bar graph with values smaller than 1 and combined it with two lines, one with positive and the other with negative larger values. When I plot it, the bar lines are much smaller and difficult to see. I would like to change the scale of the Y axis so that the bars that go from 0 to 0.5 are seen bigger. The objective would be to try to break the y axis in 2, from 0 to 0.5 and the rest. I thought about applying log = "y" to barplot, but the axis goes from negative to positive and cannot be logged. (Error in barplot.default(data$bv, data$year, ylim = c(-3, 3), log = "y") : log scale error: at least one 'height + offset' value <= 0 ). Any ideas about how to solve this?
data <- data.frame(c(2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018))
data$bv <- as.numeric(c(0.29,-0.15,0.1, 0.3, 0.2, -0.1, 0.25, -0.2, -0.3,0.08,-0.54, -0.24, -0.15, 0.26, 0.12, 0.23,-0.16,0.3))
data$pvp <- as.numeric(rep(c(2.8,2.9,3),times=6))
data$pvn <- as.numeric(rep(c(-2.8,-2.9,-3),times=6))
data$year <- as.numeric(c(2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018))
bar <- barplot(data$bv, data$year, ylim=c(-3,3))
par(new = T)
plot(data$pvp,ylim=c(-3,3),axes=F,xlab="",ylab="",type="b",lty=3,lwd=1.5,pch=15,cex=0.8)
points(data$pvn,type="b",lty=3,lwd=1.5,pch=17,cex=0.8)
You could take the log of the absolute value, then multiply that by the sign of the original value:
data$bv <- log(abs(data$bv)) * sign(data$bv)
Which gives you this:

How to put labels between columns in a bar plot in R?

I'm a beginner with R and looking for help with plotting.
I would like to make a distribution plot in R that looks like a histogram of continuous data bucketed into columns with x-axis labels between each column to denote the range captured in each column.
Instead of continuous data though, I only have the bucketed counts. I can create a plot with barplot, however I can't find a way to label BETWEEN the columns to denote the range captured in each bar.
I've tried barplot but cannot get the labels to fall between columns instead of being treated as column labels and falling directly beneath each column.
dat$freq = c(5,15,20,10)
dat$mid = c(-1.5,-.5,.5,1.5) #midpoint in each bucketed range
dat$perc = dat$freq/sum(dat$freq)
barplot(dat$perc, names.arg = dat$mid)
Each column is labeled with the midpoint. I would instead like the labels to be -2,-1,0,1,2 BETWEEN the columns.
Thank you!
edit: dput(dat) outputs:
list(freq = c(5, 15, 20, 10), mid = c(-1.5, -0.5, 0.5, 1.5), perc =
c(0.1, 0.3, 0.4, 0.2))
Is this what you're after?
df <- data.frame(freq = c(5, 15, 20, 10), mid = c(-1.5, -0.5, 0.5, 1.5), perc = c(0.1, 0.3, 0.4, 0.2))
I'm using the awesome and highly customisable library ggplot2 to plot this, which renders the plot as I think you want it. You can install this with install.packages('ggplot2'):
# install.packages('ggplot2')
library(ggplot2)
p <- ggplot(df)
p <- p + geom_bar(aes(mid, perc), stat='identity')
p

Barchart with reverse y-scale in lattice

I want a lattice barchart that looks like ggplot barchart with reverse y axis from here
http://www.sthda.com/english/wiki/ggplot2-rotate-a-graph-reverse-and-flip-the-plot
In other words, I want to turn the barchart in lattice upside down, with the origin of bars at the top. I looked for the solution for quite some time thinking it should be easy, yet failed to find one...
require(lattice)
data <- data.frame(y = c(0.1, 0.4, 0.3, 0.23, 0.17, 0.27), x = c(1,2,3,4,5,6))
histogram <- barchart(data$y ~ data$x, horizontal = FALSE)
histogram
The code above produces regular barchart. What I want to do is to make bars start from the top, not from the bottom, with y scale reversed. In other words, I want this exact graph, but upside down.
Here's one trick to do that:
plot the -y instead of y, and specify that the origin is 0, then you can change the labels on the y axis as you see fit
mydata <- data.frame(y = c(0.1, 0.4, 0.3, 0.23, 0.17, 0.27), x = c(1,2,3,4,5,6))
# fix where you want the ticks to be
ticks_at <- seq(-0.5, 0, 0.1)
barchart(-y ~ x,
mydata,
horizontal = FALSE,
origin=0,
# set the position of the ticks and their labels
scales = list(y=list(at = ticks_at,
labels = -1 * (ticks_at))),
xlab = "x-Axis",
ylab ="y-Axis")
You'll get something like this :

Indicating the statistically significant difference in bar graph base R

This has been asked before in this post: Indicating the statistically significant difference in bar graph USING R. However, they wanted to know how to do this using ggplot2. I was wondering how you do this using just the base package or function barplot().
I want something that looks like this image below:
http://i.stack.imgur.com/3I6El.jpg
my current code:
barcenter3<- barplot(newMEANs3$Percent_Viability, names.arg=c("Control", "Cyp28d1", "A3", "A4"), ylab = "Average Emergent", ylim=c(0, 1.1), xlab= "RNAi Line", main = "Trip Nicotine UAS-RNAi Emergents")
segments(barcenter3, newMEANs3$Percent_Viability-newSDs3$Percent_Viability, barcenter3, newMEANs3$Percent_Viability+newSDs3$Percent_Viability, lwd=1);
segments(barcenter3 - 0.1, newMEANs3$Percent_Viability-newSDs3$Percent_Viability, barcenter3 + 0.1, newMEANs3$Percent_Viability-newSDs3$Percent_Viability, lwd=1);
segments(barcenter3 - 0.1, newMEANs3$Percent_Viability+newSDs3$Percent_Viability, barcenter3 + 0.1, newMEANs3$Percent_Viability+newSDs3$Percent_Viability, lwd=1);
dev.off();
I want to add p value comparing contrast.
Here is a simple function to do this.
## Sample Data
means <- seq(10,40,10)
pvals <- seq(0.01, 0.05, 0.02)
barPs <- function(means, pvals, offset=1, ...) {
breaks <- barplot(means, ylim=c(0, max(means)+3*offset), ...)
ylims <- diff(means) + means[-length(means)] + offset
segments(x0=breaks[-length(breaks)], y0=ylims, x1=breaks[-1], y1=ylims)
segments(x0=c(breaks[-length(breaks)], breaks[-1]),
y0=rep(ylims, each=2), y1=rep(ylims-offset/2, each=2))
text(breaks[-length(breaks)]+diff(breaks[1:2])/2, ylims+offset,
labels=paste("p=", pvals))
}
barPs(means, pvals, offset=1, main="Bar w/ P-value",
names.arg=toupper(letters[1:4]))

Resources