I have a some data that I want to display graphically. Here's what it looks like:
data<- c(0.119197746, 0.054207788, 0.895580411, 0.64861727, 0.143249592,
0.284314897, 0.070027632, 0.297172433, 0.183569184, 0.713896071,
1.942425326, 1)
Using this command:
barplot(data, main="Ratio of Lipidated and Unlipidated LC3 I & II forms\nNormalized
to GAPDH", names.arg = c("PT250", "PT219", "PT165", "PT218", "PT244", "PT253", "PT279", "PT281",
"PT240", "PT262", "PT264", "CCD"), ylab = "Fold LC3 II/LC3I/GAPDH")
I produced this graph:
I would like to position the X-axis at 1 so that all values less-than-one will appear as down bars. I could achieve the desired affect by simply subtracting 1 from all of the values and plotting again but this would cause the numbers on the y-axis to be inaccurate. Is there some way to get R to plot values less than 1 as down bars?
Solution with custom axis.
barplot(data - 1, main="Ratio of Lipidated and Unlipidated LC3 I & II forms\nNormalized
to GAPDH", names.arg = c("PT250", "PT219", "PT165", "PT218", "PT244", "PT253", "PT279", "PT281",
"PT240", "PT262", "PT264", "CCD"), ylab = "Fold LC3 II/LC3I/GAPDH",
axes = F, ylim = c(-1, 1)
my_labs <- seq(-1, 1, by = 0.5)
axis(side = 2, at = my_labs, labels = my_labs + 1)
Related
This question already has answers here:
Different colors for lines as opposed to points in R
(3 answers)
Plot with conditional colors based on values in R [duplicate]
(2 answers)
Closed 3 years ago.
I am representing the "nature" of an interaction amongst independent variables via a line graph, on this graph the nature of the interaction changes above and below the calculated value w0. Below this value, there is a buffering effect and above there is a magnification effect. I want to represent the magnification effect with a green line and the buffering effect with a red line.
When using a line, the line does not change colors according to the conditional. However, when I use points instead, the points change colors correctly but the points are so sparse that it is hard to measure the results.
I have played around with the ifelse() function trying to change the color of the line, but as stated previously, it does not work with the line only the points.
wLow = 0
w0 = 1.49
wHigh = 4
z = yaxis <- c(1,2,3)
t = xaxis <- c(wLow,w0,wHigh)
distPlot <- plot(t,z, type="b", lwd=5, pch=15, col = ifelse( t <
w0,'red','green'), xlab="Moderator Range", ylab="Effect")
Optimally, I would like the line below w0 to be red and above to be green or if this is not possible, could we create a line of points of the correct color between the 3 given points?
graphics.off()
plot(t, z, type="n", xlab="Moderator Range", ylab="Effect")
lines(t[t <= w0], z[t <= w0], col = "red", lwd = 5)
lines(t[t >= w0], z[t >= w0], col = "green", lwd = 5)
points(t, z, pch = 19, cex = 2, col = "white")
points(t,z, pch=15, col = ifelse( t < w0,'red','green'))
One solution is to draw the line segments first, then add the points.
Note that a blank plot must be started first. This is done with plot(..., type = "n").
z0 <- c(1, 2)
t0 <- c(wLow, w0)
z1 <- c(2, 3)
t1 <- c(w0, wHigh)
plot(t, z,type = "n", xlim = range(t), ylim = range(z),
xlab = "Moderator Range", ylab = "Effect")
segments(t0, z0, t1, z1, lwd = 5, col = ifelse(t < w0, 'red', 'green'))
points(t, z, pch = 15, col = ifelse(t < w0, 'red', 'green'))
I have 2 groups of data (top and bottom) that I have been able to make boxplots for separately, but cannot get them to show in the same graph. I want them side by side for comparison for each gene tested (12 total). So, I would like to have the x-axis labeled with the gene tested, and the y-axis with the ddCt values, with 2 boxplots (1 for the top, 1 for the bottom) for each gene. I have the code for each one separately that works below:
# boxplot of first group
boxplot(Top25[-1], main = "Top Performers Gene Expression Relative to 16S", ylab = "ddCt Values", xlab = "Biofilm Gene", cex.axis = 0.75)
# boxplot of second group
boxplot(Bottom25 [-1], main = "Bottom Performers Biofilm Gene Expression Relative to 16S", ylab = "ddCt Values", xlab = "Biofilm Gene", cex.axis = 0.75)
Any suggestions for what I may try? I've tried to "melt" them together following another ggplot2 question and got an error saying "object melt was not found". Thanks for any help!
Here is an example. The main idea is to use add = TRUE to add boxplot to an existing plot and specify the horizontal position of boxplot with at
#DATA
set.seed(42)
top = rnorm(40)
bottom = rnorm(40)
#Create Empty Plot
plot(1, 1, type = "n", xlim = c(0, 3), ylim = range(c(top, bottom)),
ann = FALSE, xaxt = "n")
#Add boxplots to existing plot
boxplot(x = top, at = 1, add = TRUE)
boxplot(x = bottom, at = 2, add = TRUE)
axis(1, at = c(1, 2), labels = c("top", "bottom"))
You can do this:
Top25 <- data.frame(gene=1:40, exp=rnorm(40, 2))
Bottom25 <- data.frame(gene=41:80, exp=rnorm(40, -2))
boxplot(list(Top25[, -1], Bottom25[, -1]), names=c("Top25", "Bottom25"))
This question already has answers here:
How can I plot with 2 different y-axes?
(6 answers)
Closed 6 years ago.
i'm having troubles in a multi axis barplot. I have an X,Y axis with bars and dots in the same graph. The point is that I have to shown both of them in different scales
While I can shown both (bars and dots) correctly, the problem comes when I try to set different scales in left and right axis. I dont know how to change the aditional axis scale, and how to bind the red dots to the right axis, and the bars to the left one.
This is my code and what I get:
labels <- value
mp <- barplot(height = churn, main = title, ylab = "% churn", space = 0, ylim = c(0,5))
text(mp, par("usr")[3], labels = labels, srt = 45, adj = c(1.1,1.1), xpd = TRUE, cex=.9)
# Population dots
points(popul, col="red", bg="red", pch=21, cex=1.5)
# Churn Mean
media <- mean(churn)
abline(h=media, col = "black", lty=2)
# Population scale
axis(side = 4, col= "red")
ylim= c(0,50)
ylim= c(0,5)
What I want is to have left(grey) axis at ylim=c(0,5) with the bars bound to that axis. And the right(red) axis at ylim=c(0,50) with the dots bound to that axis...
The goal is to represent bars and points in the same graph with diferent axis.
Hope I explained myself succesfully.
Thanks for your assistance!
Here is a toy example. The only "trick" is to store the x locations of the bar centers and the limits of the x axis when creating the barplot, so that you can overlay a plot with the same x axis and add your points over the centers of the bars. The xaxs = "i" in the call to plot.window indicates to use the exact values given rather than expanding by a constant (the default behavior).
set.seed(1234)
dat1 <- sample(10, 5)
dat2 <- sample(50, 5)
par(mar = c(2, 4, 2, 4))
cntrs <- barplot(dat1)
xlim0 <- par()$usr[1:2]
par(new = TRUE)
plot.new()
plot.window(xlim = xlim0, ylim = c(0, 50), xaxs = "i")
points(dat2 ~ cntrs, col = "darkred")
axis(side = 4, col = "darkred")
I'd like to make a histogram of my variable "sex" with the values 1 = male and 2 = female. My code works properly, but I'd like to have only the values 1 and 2 on the x-axis (at the moment R prints all values between 0 and 1 in steps which makes less sense in the case of sex).
hist(g1_sex,
main = "Häufigkeitsverteilung Geschlecht",
sub = "1 = männlich, 2 = weiblich",
xlab = "Geschlecht",
ylab ="Häufigkeit",
ylim = c(0,120),
col = "lightblue",
labels = TRUE,
breaks=2)
I already tried to do it with
breaks = seq (1,2,1)
but this doesn't look nice too.
I would be very thankful for every hint of you!
Best wishes!
I think you really want barplot. See examples:
set.seed(0); x <- rbinom(500, 1, 0.3) ## generate toy 0-1 data
y <- table(x) ## make contingency table
names(y) <- c("male", "female")
ylim = c(0, 1.2 * max(y)) ## set plotting range
z <- barplot(y, space = 0, col = 5, main = "statistics", ylim = ylim)
text(z, y + 20, y, cex = 2, col = 5) ## add count number above each bar
I have also give solutions to add number above each bar, by setting extra space on the top using ylim, and use text to put texts.
Note that barplot also accepts main, etc, so you can add other annotations if you want.
I'd like to do a vertical histogram. Ideally I should be able to put multiple on a single plot per day.
If this could be combined with quantmod experimental chart_Series or some other library capable of drawing bars for a time series that would be great. Please see the attached screenshot. Ideally I could plot something like this.
Is there anything built in or existing libraries that can help with this?
I wrote something a year or so ago to do vertical histograms in base graphics. Here it is, with a usage example.
VerticalHist <- function(x, xscale = NULL, xwidth, hist,
fillCol = "gray80", lineCol = "gray40") {
## x (required) is the x position to draw the histogram
## xscale (optional) is the "height" of the tallest bar (horizontally),
## it has sensible default behavior
## xwidth (required) is the horizontal spacing between histograms
## hist (required) is an object of type "histogram"
## (or a list / df with $breaks and $density)
## fillCol and lineCol... exactly what you think.
binWidth <- hist$breaks[2] - hist$breaks[1]
if (is.null(xscale)) xscale <- xwidth * 0.90 / max(hist$density)
n <- length(hist$density)
x.l <- rep(x, n)
x.r <- x.l + hist$density * xscale
y.b <- hist$breaks[1:n]
y.t <- hist$breaks[2:(n + 1)]
rect(xleft = x.l, ybottom = y.b, xright = x.r, ytop = y.t,
col = fillCol, border = lineCol)
}
## Usage example
require(plyr) ## Just needed for the round_any() in this example
n <- 1000
numberOfHists <- 4
data <- data.frame(ReleaseDOY = rnorm(n, 110, 20),
bin = as.factor(rep(c(1, 2, 3, 4), n / 4)))
binWidth <- 1
binStarts <- c(1, 2, 3, 4)
binMids <- binStarts + binWidth / 2
axisCol <- "gray80"
## Data handling
DOYrange <- range(data$ReleaseDOY)
DOYrange <- c(round_any(DOYrange[1], 15, floor),
round_any(DOYrange[2], 15, ceiling))
## Get the histogram obects
histList <- with(data, tapply(ReleaseDOY, bin, hist, plot = FALSE,
breaks = seq(DOYrange[1], DOYrange[2], by = 5)))
DOYmean <- with(data, tapply(ReleaseDOY, bin, mean))
## Plotting
par(mar = c(5, 5, 1, 1) + .1)
plot(c(0, 5), DOYrange, type = "n",
ann = FALSE, axes = FALSE, xaxs = "i", yaxs = "i")
axis(1, cex.axis = 1.2, col = axisCol)
mtext(side = 1, outer = F, line = 3, "Length at tagging (mm)",
cex = 1.2)
axis(2, cex.axis = 1.2, las = 1, line = -.7, col = "white",
at = c(75, 107, 138, 169),
labels = c("March", "April", "May", "June"), tck = 0)
mtext(side = 2, outer = F, line = 3.5, "Date tagged", cex = 1.2)
box(bty = "L", col = axisCol)
## Gridlines
abline(h = c(60, 92, 123, 154, 184), col = "gray80")
biggestDensity <- max(unlist(lapply(histList, function(h){max(h[[4]])})))
xscale <- binWidth * .9 / biggestDensity
## Plot the histograms
for (lengthBin in 1:numberOfHists) {
VerticalHist(binStarts[lengthBin], xscale = xscale,
xwidth = binWidth, histList[[lengthBin]])
}
Violin plots might be close enough to what you want. They are density plots that have been mirrored through one axis, like a hybrid of a boxplot and a density plot. (Much easier to understanding by example than description. :-) )
Here is a simple (somewhat ugly) example of the ggplot2 implementation of them:
library(ggplot2)
library(lubridate)
data(economics) #sample dataset
# calculate year to group by using lubridate's year function
economics$year<-year(economics$date)
# get a subset
subset<-economics[economics$year>2003&economics$year<2007,]
ggplot(subset,aes(x=date,y=unemploy))+
geom_line()+geom_violin(aes(group=year),alpha=0.5)
A prettier example would be:
ggplot(subset,aes(x=date,y=unemploy))+
geom_violin(aes(group=year,colour=year,fill=year),alpha=0.5,
kernel="rectangular")+ # passes to stat_density, makes violin rectangular
geom_line(size=1.5)+ # make the line (wider than normal)
xlab("Year")+ # label one axis
ylab("Unemployment")+ # label the other
theme_bw()+ # make white background on plot
theme(legend.position = "none") # suppress legend
To include ranges instead of or in addition to the line, you would use geom_linerange or geom_pointrange.
If you use grid graphics then you can create rotated viewports whereever you want them and plot to the rotated viewport. You just need a function that will plot using grid graphics into a specified viewport, I would suggest ggplot2 or possibly lattice for this.
In base graphics you could write your own function to plot the rotated histogram (modify the plot.histogram function or just write your own from scratch using rect or other tools). Then you can use the subplot function from the TeachingDemos package to place the plot wherever you want on a larger plot.