Align gridlines with ticks in base R plot - r

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')

Related

"col" argument in plot function not working when a factor value is used for x - axis

I am doing quarterly analysis, for which I want to plot a graph. To maintain continuity on x axis I have turned quarters into factors. But then when I am using plot function and trying to color it red, the col argument is not working.
An example:
quarterly_analysis <- data.frame(Quarter = as.factor(c(2020.1,2020.2,2020.3,2020.4,2021.1,2021.2,2021.3,2021.4)),
AvgDefault = as.numeric(c(0.24,0.27,0.17,0.35,0.32,0.42,0.38,0.40)))
plot(quarterly_analysis, col="red")
But I am getting the graph in black color as shown below:
Converting it to a factor is not ideal to plot unless you have multiple values for each factor - it tries to plot a box plot-style plot. For example, with 10 observations in the same factor, the col = "red" color shows up as the fill:
set.seed(123)
fact_example <- data.frame(factvar = as.factor(rep(LETTERS[1:3], 10)),
numvar = runif(30))
plot(fact_example$factvar, fact_example$numvar,
col = "red")
With only one observation for each factor, this is not ideal because it is just showing you the line that the box plot would make.
You could use border = "red:
plot(quarterly_analysis$Quarter,
quarterly_analysis$AvgDefault, border="red")
Or if you want more flexibility, you can plot it numerically and do a little tweaking for more control (i.e., can change the pch, or make it a line graph):
# make numeric x values to plot
x_vals <- as.numeric(substr(quarterly_analysis$Quarter,1,4)) + rep(seq(0, 1, length.out = 4))
par(mfrow=c(1,3))
plot(x_vals,
quarterly_analysis$AvgDefault, col="red",
pch = 7, main = "Square Symbol", axes = FALSE)
axis(1, at = x_vals,
labels = quarterly_analysis$Quarter)
axis(2)
plot(x_vals,
quarterly_analysis$AvgDefault, col="red",
type = "l", main = "Line graph", axes = FALSE)
axis(1, at = x_vals,
labels = quarterly_analysis$Quarter)
axis(2)
plot(x_vals,
quarterly_analysis$AvgDefault, col="red",
type = "b", pch = 7, main = "Both", axes = FALSE)
axis(1, at = x_vals,
labels = quarterly_analysis$Quarter)
axis(2)
Data
set.seed(123)
quarterly_analysis <- data.frame(Quarter = as.factor(paste0(2019:2022,
rep(c(".1", ".2", ".3", ".4"),
each = 4))),
AvgDefault = runif(16))
quarterly_analysis <- quarterly_analysis[order(quarterly_analysis$Quarter),]

How to change y-axis scale in R boxplot function

When I do a boxplot diagram with the R boxplotfunction, this function prints the y-axis automatically.
library(datasets)
boxplot(cars[c('speed', 'dist')],
col = "lightgray")
In the ?boxplot I found the ylim parameter that change the y-axis limits, but not change the scale. So I tried to use the axis function to divide the scale from 0 to 120 every 10:
axis(4, at = seq(0, 120, 10)). But I'm not getting a satisfactory result.
I can't see where I'm making mistakes. Could someone help with this question?
Thanks in advance.
library(datasets)
boxplot(cars[c('speed', 'dist')], col = "lightgray", ylim = range(0:120), yaxs = "i")
axis(4, at=seq(0, 120, 10))
The y-axis is on the right-hand side as you wanted I believe.
You could use ggpubr instead. It let's you treat it as a gg object.
librabry(ggpubr)
library(reshape2)
df <- melt(cars)
p <- ggpubr::ggboxplot(data = df, x = "variable", y = "value", width = 0.8) +
ggtitle("Plot of car") +
xlab("my-xalabel") + ylab("my-ylabel")
>p
If you want in log scale:
p + ggpubr::yscale("log2", .format = TRUE)
I am answering because the OP said in a comment that my comment did the job. I will also explain the code here.
There are two tricks to consider:
First plot without the yaxis by setting argument yaxt = "n".
Then plot the axis number 2, with the labels always perpendicular to the axis. This is done with las = 2.
So the final code is the following.
library(datasets)
boxplot(cars[c('speed', 'dist')],
col = "lightgray", yaxt = "n")
axis(2, at = seq(0, 120, 10), las = 2)

R draw lines over two different scales

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.

How do I plot a legend next to my title (outside plot) using R?

I'm using base R plot(), and I want a legend (a color block and key) to show up above (outside) the top right of my plot next to my title (generated using title()).
What's the best way to do this?
Maybe something like this is what you're looking for:
x <- c(1,2,3,4)
y <- c(4,1,3,2)
z <- c(1,2,3,4)
dat <- data.frame(x,y,z)
windows(width = 5, height = 9) #quartz() on Mac
layout(matrix(c(1,2), 2, 1, byrow = TRUE), heights=c(0.5,1))
par(oma = c(4,3,0,0) + 0.1, mar = c(0,0,1,1) + 0.1)
plot(dat$x, y=rep(1,4), type = "n", axes = F, ylab = "", xlab = "")
legend(x = "bottomright", legend = c("y", "z"), fill = c("blue", "red"))
plot(dat$x, dat$y, type = "n", main = "PLOT")
lines(z, col = "red")
lines(y, col = "blue")
Basically this makes two plots, one is just invisible and shortened so all that's displayed is the legend.
You may be able to addtionally tweak the margins around the legend and other graphical parameters (?par) to get the layout better.

Put one line chart and bar chart in one plot in R (Not ggplot)?

how to
Combine a bar chart and line in single plot in R (from different data sources)?
Say I have two data sources as:
barData<-c(0.1,0.2,0.3,0.4) #In percentage
lineData<-c(100,22,534,52,900)
Note that they may not be in the same scale.
Can I plot both barData and LineData in one plot and make them good looking ?
I cant use ggplot in this case so this is not a duplicated question..
Something like the following:
Maybe this helps as a starting point:
par(mar = rep(4, 4))
barData<-c(0.1,0.2,0.3,0.4) * 100
y <- lineData<-c(100,22,534,900);
x <- barplot(barData,
axes = FALSE,
col = "blue",
xlab = "",
ylab = "",
ylim = c(0, 100) )[, 1]
axis(1, at = x, labels = c("Julia", "Pat", "Max", "Norman"))
ats <- c(seq(0, 100, 15), 100); axis(4, at = ats, labels = paste0(ats, "%"), las = 2)
axis(3, at = x, labels = NA)
par(new = TRUE)
plot(x = x, y = y, type = "b", col = "red", axes = FALSE, xlab = "", ylab = "")
axis(2, at = c(pretty(lineData), max(lineData)), las = 2)
mtext(text="Lines of code by Programmer", side = 3, line = 1)
box()

Resources