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 :
Related
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:
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
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)
In Minitab, it is easy to create "cutpoint" histograms. Can this be done in ggplot2?
For example,
df <- data.frame(x = c(0.08, 0.21, 0.25, 0.4, 0.5, 0.6))
ggplot(df, aes(x = x)) + geom_histogram(binwidth = 0.1)
As you can see here, R defaults to "midpoint" histograms. The bar containing the 0.08 is being marked with a bar at the 0.1. The bar containing the 0.21 and 0.25 is being marked at the 0.2 and so forth.
Can I somehow change these bars so the first bar covers the area between 0 and 0.1, and the second bar covers the area between 0.2 and 0.3, and so forth?
You can get rid of the problem in two ways: using parameter "center" or using "boundary". With "center" you can specify the center of one of the bins, "boundary" is similar but you specify the value of a boundary between two bins. Worth noting that "center" and "boundary" can be either above or below the range of the data, in this case the value provided will be shifted of an adequate number of widths.
In this case you already know the width of the bin, its boundaries, so with this parameters you can easily do what you asked:
library(ggplot2)
df <- data.frame(x = c(0.08, 0.21, 0.25, 0.4, 0.5, 0.6))
# This is "center" solution:
ggplot(df, aes(x = x)) + geom_histogram(binwidth = 0.1, center=0.05)
# This is with "boundary" parameter
ggplot(df, aes(x = x)) + geom_histogram(binwidth = 0.1, boundary=0.1)
You can find details and more information on the reference ?geom_histogram.
Hope this helps
I have succeeded in creating and aligning three scatter-plots in R, using the following code:
par(mfrow = c(3,1))
plot(CGP.GOSL ~ FPT.MAF.GOSL, data = all.locs, main = "A. Place I")
abline(h=c(0.5))
abline(v=c(0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5), lty=2)
plot(CGP.IRE ~ FPT.MAF.IRE, data = all.locs, main = "B. Place II")
abline(h=c(0.5))
abline(v=c(0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5), lty=2)
plot(CGP.BAR ~ FPT.MAF.BAR, data = all.locs, main = "C. Place III")
abline(h=c(0.5))
abline(v=c(0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5), lty=2)
What I would like to do now is save space by having a single Axis label for the x and y axis. I have tried experimenting with the par() function, inserting x and ylab functions, but it seems that as these are not graphical parameters is will not accept them. I suspect the problem lies in where I place this information in the code, as using the xlab and ylab seems to make sense, and I can write x and ylab = "" in the individual plot codes.
I am also struggling to change the position of the main titles so that the appear on the left, to remove the values from the x-axis so that they only show at the bottom of the whole figure, and to arrange the figure so that there is less space.
This figure shows the current layout and the layout I want to achieve:
I am sorry to post so many questions at once. I am very new to R and programming am still finding the helpfiles a bit daunting, although I am getting there. Some suggestions on functions, where to put them and how to use them to achieve some of these aims would be great.
The documentation can be a bit challenging at times. Here's a skeleton for what I think you're looking for:
# 3 rows
par(mfrow=c(3,1))
# tighter margins
par(mar = c(0, 0, 0, 0), oma = c(4, 4, 0.5, 0.5))
# need some data
data(cars)
# 3 plots, no axis junk
plot(cars, ann=FALSE)
plot(cars, ann=FALSE)
plot(cars, ann=FALSE)
# outer labels
mtext("x axis", side = 1, outer = TRUE, cex = 0.7, line = 2.2)
mtext("y axis", side = 2, outer = TRUE, cex = 0.7, line = 2.2)
This answer is based on hrbrmstr's answer, but the result is closer to the requested layout:
# 3 rows
par(mfrow=c(3,1))
# Adjust margins. Each vector element refers to one side of the plot;
# the order is c(bottom, left, top, right). (See ?par)
par(mar = c(2.5, 4.1, 1, 2.1), oma = c(3, 3, 2, 0))
# need some data
data(cars)
# 3 plots. On the first two: Suppress axis labels (ann = FALSE) and
# the x axis (xaxt = "n"), then add the ticks using axis() and the
# title using mtext(). On the last one, do not suppress x axis.
# Note that repeating arguments could be set globally using par().
plot(cars, ann = FALSE, xaxt = "n")
axis(side = 1, labels = FALSE)
mtext(text = "A. Place I", side = 3, at = par("usr")[1], line = 1)
plot(cars, ann=FALSE, xaxt = "n")
axis(side = 1, labels = FALSE)
mtext(text = "B. Place II", side = 3, at = par("usr")[1], line = 1)
plot(cars, ann=FALSE)
mtext(text = "C. Place III", side = 3, at = par("usr")[1], line = 1)
# outer labels
mtext("X Axis label", side = 1, outer = TRUE)
mtext("Y Axis label", side = 2, outer = TRUE)