I'm ploting a vector of 29 values in a plot using:
plot(0:29, v, type="o", main="Title of the plot")
I try to adjust the grid to be unit by unit using:
grid(31, lw=2)
The problem is that x axis first value (0 position) doesn't start at the begining of the graph and grid starts at the begining, so both elements aren't aligned.
How can solve this issue?
Use abline instead.
plot(0:10)
abline(h = 0:10)
abline(v = 0:10)
You can also force the exact x and y limits:
plot(0:10, 0:10, xlim = c(0,10), ylim = c(0, 10), xaxs = "i", yaxs = "i")
grid(10)
In general, using abline is easier and more robust. I also often plot with type = "n", add lines/whatever in the background, then add the points.
Related
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)
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.
I am now trying to plot the Probability Density Functuion of some data, and I find the is some distance between y=0and x axis. I tried to set yaxs="i", but then the x axis will become grey. Is there any solution? Thanks. Here is an example
set.seed(100)
plot(density(rnorm(100)),xlab="",ylab="",main="")
plot(density(rnorm(100)),yaxs="i",xlab="",ylab="",main="")
As you can see, the color of the x axis will become grey. How to make it black?
The reason you get the gray line is that you are calling plot.density when you pass an object class density to plot. plot.density has a zero.line argument which is set to TRUE and plots the gray line using abline(h = 0, lwd = 0.1, col = "gray") by default (see stat:::plot.density for code). You need to set zero.line to FALSE.
plot(density(nums), yaxs="i",
xlab="", ylab="", main="",
zero.line = FALSE)
You can control the upper ylim too if you want to give some more room at the top than yaxs = "i" would give otherwise. Of course, you still need zero.line = FALSE to not plot the gray zero line.
plot(density(nums), yaxs="i",
xlab="", ylab="", main="",
zero.line = FALSE,
ylim = c(0, 0.5)) # put whatever you want here instead 0.5
An alternative solution would be to cover the gray line with another line:
plot(density(nums), yaxs="i",
xlab="", ylab="", main="")
abline(h = 0)
If you specify the ylim, it should work.
d <- density(rnorm(100))
plot(d, xlab = "", ylab = "", ylim = c(0,max(d$y)), yaxs = "i")
you could also specify
par(col.axis = "black")
Looks as follows, i.e., starting at 0 and keeping the color.
d <- density(rnorm(100))
plot(d, xlab = "", ylab = "", ylim = c(0,max(d$y)+.05), yaxs = "i",
col.axis = "black")
I want to get rid the small margin close to zero on X and Y value (red line on pic), and plot ONLY what is showed in red square.
I tried setting par(mar = rep(0, 4) and xlim=c(0, ...), ylim=c(0, ...) but R still keeps adding this tiny margin. How to get rid of it?
EDIT:
another point of view on my problem:
after running:
require(plotrix)
axisRange <- c(0,500)
plot(NULL, xlim = axisRange, ylim=axisRange)
draw.circle(0, 0, 200, col = "white", border = "red")
I end up with a circle positioned not in "true" 0,0 point:
EDIT2:
Actually what I want to do, is to plot circles of different radius, and save it as an image. That is why I care about the margins.
I end up with something like this (spots on the corners are for the reference):
And should be more like this:
You can set the xaxs and yaxs arguments to "i" as opposed to the default of "r". From the par help page:
Style "r" (regular) first extends the data range by 4 percent at each
end and then finds an axis with pretty labels that fits within the
extended range.
Style "i" (internal) just finds an axis with pretty labels that fits
within the original data range.
library(plotrix)
axisRange <- c(0,500)
par(mar = rep(0,4))
plot(NULL, xlim = axisRange, ylim=axisRange, xaxs = "i", yaxs = "i")
draw.circle(0, 0, 200, col = "white", border = "red")
Gives:
I am trying to get the x axis labels to be rotated 45 degrees on a barplot with no luck. This is the code I have below:
barplot(((data1[,1] - average)/average) * 100,
srt = 45,
adj = 1,
xpd = TRUE,
names.arg = data1[,2],
col = c("#3CA0D0"),
main = "Best Lift Time to Vertical Drop Ratios of North American Resorts",
ylab = "Normalized Difference",
yaxt = 'n',
cex.names = 0.65,
cex.lab = 0.65)
use optional parameter las=2 .
barplot(mytable,main="Car makes",ylab="Freqency",xlab="make",las=2)
EDITED ANSWER PER DAVID'S RESPONSE:
Here's a kind of hackish way. I'm guessing there's an easier way. But you could suppress the bar labels and the plot text of the labels by saving the bar positions from barplot and do a little tweaking up and down. Here's an example with the mtcars data set:
x <- barplot(table(mtcars$cyl), xaxt="n")
labs <- paste(names(table(mtcars$cyl)), "cylinders")
text(cex=1, x=x-.25, y=-1.25, labs, xpd=TRUE, srt=45)
Rotate the x axis labels with angle equal or smaller than 90 degrees using base graphics. Code adapted from the R FAQ:
par(mar = c(7, 4, 2, 2) + 0.2) #add room for the rotated labels
#use mtcars dataset to produce a barplot with qsec colum information
mtcars = mtcars[with(mtcars, order(-qsec)), ] #order mtcars data set by column "qsec"
end_point = 0.5 + nrow(mtcars) + nrow(mtcars) - 1 #this is the line which does the trick (together with barplot "space = 1" parameter)
barplot(mtcars$qsec, col = "grey50",
main = "",
ylab = "mtcars - qsec", ylim = c(0,5 + max(mtcars$qsec)),
xlab = "",
xaxt = "n", # Do not plot the default labels
space = 1)
#rotate 60 degrees (srt = 60)
text(seq(1.5, end_point, by = 2), par("usr")[3]-0.25,
srt = 60, adj = 1, xpd = TRUE,
labels = paste(rownames(mtcars)), cex = 0.65)
You can simply pass your data frame into the following function:
rotate_x <- function(data, column_to_plot, labels_vec, rot_angle) {
plt <- barplot(data[[column_to_plot]], col='steelblue', xaxt="n")
text(plt, par("usr")[3], labels = labels_vec, srt = rot_angle, adj = c(1.1,1.1), xpd = TRUE, cex=0.6)
}
Usage:
rotate_x(mtcars, 'mpg', row.names(mtcars), 45)
You can change the rotation angle of the labels as needed.
You may use
par(las=2) # make label text perpendicular to axis
It is written here: http://www.statmethods.net/graphs/bar.html
You can use ggplot2 to rotate the x-axis label adding an additional layer
theme(axis.text.x = element_text(angle = 90, hjust = 1))
In the documentation of Bar Plots we can read about the additional parameters (...) which can be passed to the function call:
... arguments to be passed to/from other methods. For the default method these can
include further arguments (such as axes, asp and main) and graphical
parameters (see par) which are passed to plot.window(), title() and axis.
In the documentation of graphical parameters (documentation of par) we can see:
las
numeric in {0,1,2,3}; the style of axis labels.
0:
always parallel to the axis [default],
1:
always horizontal,
2:
always perpendicular to the axis,
3:
always vertical.
Also supported by mtext. Note that string/character rotation via argument srt to par does not affect the axis labels.
That is why passing las=2 makes the labels perpendicular, although not at 45°.
Andre Silva's answer works great for me, with one caveat in the "barplot" line:
barplot(mtcars$qsec, col="grey50",
main="",
ylab="mtcars - qsec", ylim=c(0,5+max(mtcars$qsec)),
xlab = "",
xaxt = "n",
space=1)
Notice the "xaxt" argument. Without it, the labels are drawn twice, the first time without the 60 degree rotation.