Scatterplot numerical y against two x groups - r

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:

Related

Change x-axis intervals to be monthly in r

I have a data frame with the first column named "Date." It has values like "2016-01-01, 2016-01-02 ..." etc. The second column is named "precipBulk," and it just has decimal values (ex. 3.36, 1.57, etc.). The third column is named "abundance," and it also has decimal values. I want to graph both "abundance" and "precipBulk" on one graph(Like the image), but I want the x-axis to have intervals with every month instead of every other month like it is now. I know there's a way to do it in ggplot2 using "scale_x_date()" but I can't graph both of the y values in one graph with ggplot2 for some reason. Is there a way to do it without using ggplot2? if not, any tips on how I would graph dual y-axis to achieve this with ggplot2?
Graph link https://i.stack.imgur.com/SZXgT.png `
Small portion of data frame https://i.stack.imgur.com/PvTED.png
To make the graph, I did:
x = frame$Date
y1 = frame$precipBulk
y2 = frame$abundance
plot(x,y1, type = "l",ylab="Bulk Precipitation",xlab="Month",col="blue", main = "Precipitation vs Mosquito Abundance (OSBS 2016)", cex.main = 1)
par(new = TRUE)
plot(x, y2, type = "l",yaxt="n",xaxt="n",ylab="",col="red")
axis(side = 4)
legend('topleft', c("Precipitation", "Mosquito Abundance"), col= c("blue", "Red"),lty=c(1,1), adj = c(0,0.6), cex= 0.75)
You need to turn the x-axis off (as you did) and then add it manually, perhaps reducing the size if necessary so that the axis tick labels fit, otherwise, R will decide for you.
x <- seq(as.Date("2017-01-01"), as.Date("2018-01-01"), "day")
plot(x, rnorm(length(x)), xaxt="n")
at <- seq(min(x), max(x), "month")
axis(side=1, at=at, labels=format(at, "%b"), cex.axis=0.7)

Combining two plots side by side

I need to put two plots side by side. As such, not a hard exercise, except that:
I want and need to use basic graphics
the plots should be placed seamlessly next to each other.
Here is an example how I solve it
x2 <- seq(1.9, 7.3, length.out=10)
x1 <- seq(0.2, 5.8, length.out=10)
y1 <- rnorm(10)
par(mfrow=c(1,2))
par(mar=c(5,4,4,0))
plot(x1, y1, type="l", bty="n", xlim=range(x1), ylim=c(-2, 2))
par(mar=c(5,0,4,2))
plot(x2, y1, type="l", bty="n", xlim=rev(range(x2)), ylim=c(-2, 2), yaxt="n")
Here is the problem: I would like the two lines to touch or almost touch. If the axes are separated, that is OK; but the distance between these two plots should be minimal. Optimally, I will want to have fat red vertical line showing where the two parts of the plot meet.
None of the answers I have found so far allow me to do that.
Context: I am plotting a genomic rearrangement in which two distant parts of some chromosomes were fused together, one of them reversed (hence the different scaling).
Add xaxs = "i" into the fist par(), i.e.
par(mfrow = c(1, 2), xaxs = "i")
and run the entire code again.
xaxs indicates the style of axis interval calculation to be used for the x-axis. The default is "r"(regular) which extends the data range by 4 percent at each end. Revising it to "i" will make the x-axis fit within the original data range.
While #DarrenTsai's answer is absolutely correct, you'll find that the x-axis scales take up different values per pixel when they have different mar parameters. I suggest you consider plotting them together and then adding a custom axis.
x2 <- seq(1.9, 7.3, length.out=10)
x1 <- seq(0.2, 5.8, length.out=10)
y1 <- rnorm(10)
ValueTable <- data.frame(Foward = c(x1,max(x1) + (x2-min(x2))), Join = c(x1,rev(x2)))
plot(ValueTable$Foward,c(y1,rev(y1)),type = "l",xaxt="n",xlab = "",ylab = "Value")
axis(1, ValueTable$Foward[seq(1,nrow(ValueTable),by = 2)], labels=formatC(ValueTable$Join[seq(1,nrow(ValueTable),by = 2)],format = "f", digits = 2))
abline(v=max(x1))

How do I find the correct coordinates to align labels with barplot bars?

I'm creating a graphic that has a few different graph elements, using layout() to define plotting regions. I have a separate region for labels that need to align to bars on a barplot in an adjacent plotting region.
I can take a guess at where to plot the labels so that they line up - but the number of these locations will vary so this is not an ideal solution.
Here's an example of what I'm trying to do:
labs <- paste("Some text", letters[1:9])
datA <- table(sample(letters[1:9], size=200, replace=TRUE, prob=rep(c(0.1,0.2,0.3),3)))
layout(matrix(c(1,2,3,3), 2, 2, byrow=TRUE), widths=c(1,2), heights=c(6,1))
plot.new()
text(x=1, y=seq(0.05,1.0,0.111), labels=labs, adj=1, cex=1.4)
barplot(datA, horiz=TRUE, las=1, axes=F, yaxt="n")
How can I find the correct values to plot the labels?
(I'm aware that it looks like this can be solved by just plotting the labels with the barplot - this is not a viable solution for what I'm doing).
The output of barplot gives the heights so:
bp <- barplot(datA, horiz=TRUE, las=1, axes=F, yaxt="n")
text(0*bp, bp, labs, col = "blue", pos = 4)

How to make a gradual color bar for representation of risk analysis results in R?

I want to plot results of risk analysis that categorized by 4 levels (No risk, low, moderate and high risk) on gradual color bar (green-yellow-red).
I thought about something like this (but I'm open for nicer suggestions.)
The input is something like this
results <- data.frame(matrix(nrow = 5,ncol = 0))
results$day <- c(1:5)
results$assessment <-c("Low","Moderate","High","Low","Moderate")
I will try to give a lot of detail with my answer.
I am assuming that you want just the colorbar and not the colorbar
added to some other graph. That is what is created below.
0 Setup
library(fields) ## for the colorbar function
## create the palette
myPalette = colorRampPalette(c("green", "yellow", "orange", "red"))
1 Create an empty plot.
plot(0:1, 0:1, type="n", bty="n", xaxs="i",
xaxt="n", yaxt="n", xlab="", ylab="")
When you run this, you should get an empty plot - no axes, nothing.
Both x and y range from 0 to 1.
2 Create the color bar
colorbar.plot(0.5, 0.05, 1:100, col=myPalette(100),
strip.width = 0.2, strip.length = 1.1)
3 Add the axis labels
axis(side=1, at=seq(0,1,1/3), tick=FALSE,
labels=c("No Risk", "Low", "Moderate", "High Risk"))
4 Add the arrow.
arrows(0.7, 0.18, 0.7, 0.1, length=0, lwd=8)
arrows(0.7, 0.18, 0.7, 0.09, length=0.1, lwd=3, angle=45)
This is a bit of a hack. If I made the lines in the arrow thick,
the arrowhead was rather blunt and ugly. So the first arrows
statement makes a thick line with no arrowhead and the second one
uses a thin line and adds a sharp arrowhead.
I have the arrow at 0.7. Adjust the x values to place it elsewhere.
Result

Dot Plot in R using R Plotting

What is the best way to generate a dotplot with two factors like this, preferably using standard R plots (not ggplot) and from a 2x2 data frame. The horizontal lines should be means. I have tried cleveland dot charts, but cannot figure out how to get two data series' and have the dots jittered:
The following piece of code should do the trick:
set.seed(1)
t1 = rnorm(10); t2 = rnorm(10, 2)
t1_g2 = rnorm(10, 4);t2_g2 = rnorm(10)
##Don't print the axes labels
par(ann=FALSE)
##Plot first set of data.
##Need to check for sensible ranges
##Use the jitter function to spread data out.
plot(jitter(rep(0,10),amount=0.2), t1,
xlim=range(-0.5,3.5), ylim=range(-3,8),
axes=FALSE,frame.plot=TRUE)
points(jitter(rep(1,10), amount=0.2), t1_g2, col=2)
points(jitter(rep(2,10), amount=0.2), t2)
points(jitter(rep(3,10), amount=0.2), t2_g2, col=2)
##Add in the y-axis
axis(2, seq(-4,8,by=2))
##Add in the x-axis labels
mtext("Treatment 1", side = 1, at=0.5)
mtext("Treatment 2", side = 1, at=2.5)
##Add in the means
segments(-0.25, mean(t1), 0.25, mean(t1))
segments(0.75, mean(t1_g2), 1.25, mean(t1_g2))
segments(1.75, mean(t2), 2.25, mean(t2))
segments(2.75, mean(t2_g2), 3.25, mean(t2_g2))
##Add in the legend
legend(0, 8, c("Group 1", "Group 2"), col=1:2, pch=1)
which gives:

Resources