R draw lines over two different scales - r

I have built two graphs in one (two different y axis but plotting on the same graph). I want to show the connection between the values on the left and the values on the right (Do they stay consistently > 0 or <0 or change?)
Now what I need is to link the two sides of the graph with a line to see if it decreases/increases. So I want a corresponding dot on the left to be linked to the corresponding dot on the right by a line.
But because the y axis values on the left and the right are different, I am not figuring out how this can work.
Here is my code to build the graph:
## Plot first set of data and draw its axis
plot(rep(1, length(DEG)), DEG, xlim = c(0,4), xaxt = "n",
ylim = c(-5, 5), col = "black", xlab = "", ylab = "")
axis(1, at = c(1))
## Allow a second plot on the same graph
par(new = TRUE)
## Plot the second plot and put axis scale on right
plot(rep(3, length(DMG)), DMG, axes = F, xlim = c(0, 4), xaxt = "n",
ylim = c(-80, 80), col = "black", xlab = "", ylab = "")
axis(1, at = c(3)))
axis(side = 4)
abline(h = 0, col = "red")
Does anyone have an idea? I tried the basic line:
lines(x$DEG[x$Genes == "FEX_0000936"], x$DMG[x$Genes == "FEX_0000936"],
type="o", pch=22, col="seagreen3")
Here is my graph perhaps it is clearer when seeing it:
Thanks for your help.

Related

How to superimpose two ts objects with two different axes with ts.plot in R?

library(tseries)
library(readxl)
data = read_excel(.......)
#Create tseries
equity = ts(data$EQUITY, start = c(2015,01,01), end = c(2020,01,01), frequency = 12)
cci = ts(data$CCI, start = c(2015,01,01), end = c(2020,01,01), frequency = 12)
#Plot the two series together
ts.plot(equity, cci, lty = c(1:2))
This code returns the following chart: R Chart.
Keeping in mind that I'd like to use the ts.plot function since I'm plotting other tseries objects and I'm not a fan of how ggplot2 handles them, is there a way to add a second axis to the chart and make it so that the two series appear superimposed instead of being far apart like in the linked image? The desired result would be like in this chart plotted with Python and matplotlib: Python Chart, possibly with a legend, too.
Any help would be greatly appreciated, thanks!
Use plot.ts rather than ts.plot like this. (See ?legend for other legend position keywords.)
z <- ts(cbind(1:10, 110:101))
col <- c("black", "blue")
plot(z[, 1], xlab = "", ylab = "", yaxt = "n", col = col[1])
axis(2, col.axis = col[1])
par(new = TRUE)
plot(z[, 2], xlab = "", ylab = "", yaxt = "n", col = col[2])
axis(4, col.axis = col[2])
legend("top", legend = c("z1", "z2"), lty = 1,
col = col, text.col = col)

Align gridlines with ticks in base R plot

I saw this picture on the Internet, and just wondered how to plot it in R. This is my code:
article <- data.frame(x = as.Date(round(runif(1000), 2) * 100, origin = '2017-01-01'), y = sample(letters[1:10], 1000, T))
plot(article$x, article$y, pch = 19, col = article$y, xlab = 'date', ylab = 'account', yaxt = 'n') + grid(nx = 10, ny = 10, lty = 1, col = 'grey')
axis(2, at = 1:10, label = levels(article$y))
And I got a picture like this. There is still a problem: the gridline on the y axis does not correspond to the axis label. So how to solve this problem, or is there a more direct method for rendering the plot?
I don't know how to fix the arguments of grid() so that it gives what you want but you could use plot() to draw a blank plot, use abline() to draw the grid, then plot the data on it using points().
So using your data
plot(article$x, article$y, type="n", xlab = 'date', ylab = 'account', yaxt = 'n', xaxt = 'n')
abline(h=1:10, v=pretty(article$x), col="grey")
points(article$x, article$y, pch = 19, col = article$y)
axis(2, at = 1:10, label = levels(article$y))
axis(1, at = pretty(article$x), label = format(pretty(article$x), "%b"))
Or just plot the data as you're doing and draw the grid afterwards using abline(), but in doing so the grid will be drawn on top of your data points.
ggplot produces a graph very similar to the first picture you included in your post:
library(ggplot2)
library(dplyr)
article %>%
ggplot(aes(x, y, colour=y)) + geom_point() + theme_light() + labs(x='date', y='account')

Align grid() to plot ticks

When adding ticks to a plot (more ticks than default), how does one get the grid() to align the grid to the ticks?
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,10), ylim=c(0,10))
grid(lwd=2, nx=10, ny=10)
Tried changed the xlim and different numbers for the nx arg in grid (number of cells), but the grid simply doesn't line up.
Related, but doesn't answer question: Aligning grid lines in R, bReeze package
Related, and uses workaround: Align grid with ticks
Is the workaround the most efficient option?
You could use abline to draw grids. You can specify where the grids should be with h (for horizontal lines) and v (for vertical lines)
#Plot
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,10), ylim=c(0,10))
#Add horizontal grid
abline(h = c(0,2,4,6,8,10), lty = 2, col = "grey")
#Add vertical grid
abline(v = 1:10, lty = 2, col = "grey")
Another workaround is to use axis where tck value is 1. With axis, you can specify where the grids should be with at
#Plot
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,10), ylim=c(0,10))
#Add horizontal grid
axis(2, at = c(0,2,4,6,8,10), tck = 1, lty = 2, col = "grey", labels = NA)
#Add vertical grid
axis(1, at = 1:10, tck = 1, lty = 2, col = "grey", labels = NA)
#Add box around plot
box()
The problem is that grid is putting nx grid lines in the user space, but plot is adding 4% extra space on each side. You can take control of this. Adding xaxs="i", yaxs="i" to your plot will turn off the extra space. But then your upper right point will be cut off, so you need to change the xlim and ylim values and change nx to match. Final code is:
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,11), ylim=c(0,11),
xaxs="i", yaxs="i")
grid(lwd=2, nx=11, ny=11)
The answer to your question
When adding ticks to a plot (more ticks than default), how does one get the grid() to align the grid to the ticks?
is:
Using function axis to obtain the x axis tick locations created by plot function in combination with abline
Concretely, you substitute the line
grid(lwd=2, nx=10, ny=10)
by the following three lines
x_ticks <- axis(1, 0:10, labels = FALSE)
grid(lwd = 2, ny = NULL, nx = NA)
abline(v = x_ticks, lwd = 2, lty = 3, col = "lightgray")
and the result will be
You can control both x ticks and y ticks and get rid of the grid function. In this case the 3 lines would be
x_ticks <- axis(1, 0:10, labels = FALSE)
y_ticks <- axis(2, labels = FALSE)
abline(v = x_ticks, h = y_ticks, lwd = 2, lty = 3, col = "lightgray")
I would vote for the workaround. Because if you look at manual from ?grid, it has this statement,
"Note: If more fine tuning is required, use ‘abline(h = ., v = .)’
directly."

overlaying different density curves without showing the histogram

I want to be able to show three different density curves on the same axis. I've got the code below so far but i don't know how to combine them to so that they can
curve(dnorm(x,mean=0,sd=1),col="darkgreen",xlim=c(-4,8),ylim=c(0,.8))
curve(dnorm(x,mean = 0,sd=1.5),col="red",xlim = c(-5,8),ylim=c(0,.6))
curve(dnorm(x,mean = 0.5,sd=0.5),col="black",xlim = c(-2,8), ylim =c(0,1))
This is the basic solution. You can add more formatting if need be (for axes etc). Note you need to change the xlim and ylim to match on the plots.
curve(dnorm(x,mean=0,sd=1),col="darkgreen",xlim=c(-5,8),ylim=c(0,1), ylab = "")
par(new = TRUE)
curve(dnorm(x,mean = 0,sd=1.5),col="red",xlim = c(-5,8),ylim=c(0,1), ylab = "")
par(new = TRUE)
curve(dnorm(x,mean = 0.5,sd=0.5),col="black",xlim = c(-5,8), ylim =c(0,1), ylab = "")

Plot() command to move x-axis on top of the plot

I'm trying to move the x-axis labeling and tick marks above the plot on top. Here's my code.
ucsplot <- plot(ucs, depth, main= "Depth vs. UCS", xlab = "UCS (psi)", ylab="Depth (ft)", type="l", col="blue", xlim=c(0, max(dfplot[,3]+5000)), ylim = rev(range(depth)))
ucsplot
How do I get the x-axis labeling and tick marks to appear only on top, instead of the bottom? Also, how do I get the title to not sit right on top of the numbers right above the tick marks? Also, how do I get the chart to start not offset a little bit to the right? As in the zero and starting numbers are in the corners of the plot and not offset.
Seems the OP is looking for a plot where x-axis is at top. The data has not been provided by OP. Hence using a sample dataframe, solution can be displayed as:
df <- data.frame(a = 1:10, b = 41:50)
plot(a ~ b, data = df, axes = FALSE, xlab = NA, ylab = NA)
axis(side = 2, las = 1)
axis(side = 3, las = 1)

Resources