How do I customize where my plot starts in R? [duplicate] - r

I want to set the starting point of my graph (both in the x- and y-axis) to be zero. I have used the xlim() and ylim() functions to no avail. I have attached my code below.
setwd ("D:/Rcode/Assignment_2") #setting up the working directory
LightGrowth1 <- read.csv ("LightGrowth-1.csv") #reading the file and attaching it to a dataframe
Light <- LightGrowth1$light #attach our light values to a vector in R
Growth <- LightGrowth1$growth #attach our growth values to a vector in R
Labels <- c("Light", "Growth") #create a vector using the labels
plot (Light, Growth, xlab = "Amount of Light (units)", ylab = "Plant Growth (units)",
pch = 16, col= "firebrick", xlim = c(0, max (Light)), ylim = c (0, max (Growth)),
main = "Plant Growth vs Amount of Light"
)
This is what my plot currently looks like:

Your axes do start at 0, and xlim and ylim are what you need to change that.
What I think you are referring to is the spacing between the axes and the plot.
There are two extra parameters that allow you to change that, xaxs and yaxs.
plot (x, y, xlim=c(0,10), ylim=c(0,10),
xaxs="i", yaxs="i")
This should do the trick
See the par help for more info.

Related

Plot with a normal and a reversed y axis

I have data sets containing daily precipitation and discharge data. Now I would like to plot everything in one plot. All data sets are of length 61, so they can share the same x axis. The discharge data should be plotted the "normal" way, meaning that the y axis starts at the bottom and is placed on the left side. The precipitation data should be plotted "from the top", meaning that the y axis is reversed and placed on the right side.
Here is some code for a minimal reproducible example:
precipitation <- runif(61, min=0, max=25)
discharge <- runif(61, min=370, max=2610)
The result should approximately look like this:
Anybody with an idea how to achieve this?
EDIT: thanks pascal for the answer that implies the usage of ggplot2.
I also found a way by myself to do it with Base R, in case it could help anybody in the future:
precipitation <- runif(61, min=0, max=25)
discharge <- runif(61, min=370, max=2610)
# plot with Base R
par(mar = c(5, 5, 3, 5), xpd = TRUE)
plot(precipitation, type= "l", ylim= c(0,80), ylab= "Precipitation [mm/day]", main= "Comparison",
xlab= "Day", col= "blue")
par(new = TRUE)
plot(discharge, type= "l", xaxt = "n", ylim= rev(c(0,5000)), yaxt = "n", ylab = "", xlab = "", col= "red", lty= 2)
axis(side = 4)
mtext("Discharge [m³/s]", side = 4, line = 3)
The ggplot2 way looks a bit fancier of course.
ggplot2 can be used to make plots with a second, inverted axis. One has to specify sec.axis in scale_y_continuous(). I'm using a transformation ((100-x)*100) for your data and apply it to the axis as well, so that it fits. This can be changed to any numbers.
ggplot() +
geom_line(aes(y=precipitation, x=1:61), col="orange") +
geom_line(aes(y=100-discharge/100, x=1:61), col="blue") +
scale_y_continuous(name="rain", sec.axis=sec_axis(~(100-.)*100, name= "discharge"))

How do you change the starting point of your plot in R?

I want to set the starting point of my graph (both in the x- and y-axis) to be zero. I have used the xlim() and ylim() functions to no avail. I have attached my code below.
setwd ("D:/Rcode/Assignment_2") #setting up the working directory
LightGrowth1 <- read.csv ("LightGrowth-1.csv") #reading the file and attaching it to a dataframe
Light <- LightGrowth1$light #attach our light values to a vector in R
Growth <- LightGrowth1$growth #attach our growth values to a vector in R
Labels <- c("Light", "Growth") #create a vector using the labels
plot (Light, Growth, xlab = "Amount of Light (units)", ylab = "Plant Growth (units)",
pch = 16, col= "firebrick", xlim = c(0, max (Light)), ylim = c (0, max (Growth)),
main = "Plant Growth vs Amount of Light"
)
This is what my plot currently looks like:
Your axes do start at 0, and xlim and ylim are what you need to change that.
What I think you are referring to is the spacing between the axes and the plot.
There are two extra parameters that allow you to change that, xaxs and yaxs.
plot (x, y, xlim=c(0,10), ylim=c(0,10),
xaxs="i", yaxs="i")
This should do the trick
See the par help for more info.

How change the y-axis numbers to be horizontal on an NMDS plot created in vegan?

Can I change the y-axis numbers to be horizontal on an NMDS plot created in vegan?
library(vegan)
sp <- poop[,28:34]
bat <- poop[,4:7]
mds1 <- metaMDS(sp, k=3,try=200)
plot(mds1$points[,1], mds1$points[,2], pch = as.numeric(bat$species),
col= as.numeric(bat$species),
xlab = "NMDS1", ylab= "NMDS2")
In R, the direction of labels is controlled by graphical parameter las (see ?par). You can also give this parameter in plot call for the metaMDS result. As you see from ?par, las=1 will put all labels horizontal.
More seriously, you should not plot metaMDS results like you do. It is better to use the dedicated plot method for the result, or if you want to do it all by yourself, you should at least force equal aspect ratio for axes with asp = 1 in your plot call. So the following should work:
## with metaMDS plot:
plot(mds1, display="si", las=1, type = "n") # for an empty plot
points(mds1, pch = as.numeric(bat$species), col= as.numeric(bat$species))
## or with generic plot:
plot(mds1$points[,1], mds1$points[,2], pch = as.numeric(bat$species),
col= as.numeric(bat$species),
xlab = "NMDS1", ylab= "NMDS2",
asp = 1, las = 1) # this is new

R barplots: specify intervals of date-based x-axis

I've been producing different sets of charts, all in R base. I have a problem though with barplots. I've formatted the x-axis to show the dates by year, however, many years show up several times. I would like each year to only show up once.
Here's my example code:
library(quantmod)
start <- as.Date("01/01/2010", "%d/%m/%Y")
#Download FRED data
tickers <- c("WTISPLC", "DCOILBRENTEU")
fred <- lapply(tickers, function(sym) {na.omit(getSymbols(sym, src="FRED", auto.assign=FALSE, return.class = "zoo"))})
df <- do.call(merge, fred)
#Subset for start date
df <- subset(df, index(df)>=start)
#Create bar plot
par(mar = c(5,5,5,5))
barplot(df[,2], names.arg=format(index(df), "%Y"), ann=FALSE, bty="n", tck=-0, col=1:1, border=NA, space=0); title(main="Example chart", ylab="y-axis")
This example should be reproducible and show clearly what I mean. Now, I've been researching how to add a separate x-axis and how to define that axis. So, I've tried to add the following code:
#Plot bars but without x-axis
barplot(df[,2], names.arg=format(index(df), "%Y"), ann=FALSE, bty="n", tck=-0, xaxt="n", col=1:1, border=NA, space=0); title(main="Example chart", ylab="y-axis")
# Set x-axis parameters
x_min <- min(index(df))
x_max <- max(index(df))
xf="%Y"
#Add x-axis
axis.Date(1, at=seq(as.Date(x_min), x_max, "years"), format=xf, las=1, tck=-0)
This does not give me an error message, but it also does absolutely nothing in terms of drawing an x-axis.
Please do not provide a solution for ggplot. Even though I like ggplot, these barplots are part of a bigger project for me, all using R base and I would not like to introduce ggplot into this project now.
Thanks!
If you are not limited to barplot, you may use the following very simple solution using plot.zoo behind the screens:
# only use what you want, and avoid multiple plots
df2 <- df[ , 2]
# use zoo.plot's functionality
plot(df2, main = "Example Chart", ylab = "y-axis", xlab = "")
This yields the following plot:
I know it is not a barplot, but I don't see what a barplot would add here. Please let me know, whether this is what you want or not.
Edit 1
If you do want to use barplot you may use the following code:
### get index of ts in year format
index_y <- format(index(df), "%Y")
### logical vector with true if it is the start of a new year
index_u <- !duplicated(index_y)
### index of start of new year for tick marks
at_tick <- which(index_u)
### label of start of new year
labels <- index_y[index_u]
### draw barplot without X-axis, and store in bp
### bp (bar midpoints) is used to set the ticks right with the axis function
bp <- barplot(df[,2], xaxt = "n", ylab= "y-axis")
axis(side = 1, at = bp[at_tick] , labels = labels)
yielding the following plot:
Please let me know, whether this is what you want.
Edit 2
We need to take into account two bits of information, when explaining why the ticks and labels group together at the left-hand side.
(1) in barplot, space defines the amount of space before each bar (as a fraction of the average bar width). In our case, it defaults to around zero (see ?barplot for details). In the illustration below, we use spaces of 0.0, 0.5, and 2.0
(2) Barplot returns a numeric vector with the midpoints of the bars drawn (again see the help pages for more detailed info). We can use these midpoints to add information to the graph, like we do in the following excerpt: after storing the result of barplot in bp, we use bp to set the ticks: axis(... at = bp[at_tick] ... ).
When we add space, the location of the bar midpoints change. So, when we want to use the bar midpoints after adding space, we need to be sure we have the right information. Simply stated, use the vector returned by barplot with the call where you added space. If you don't, the graph will be messed up. In the below, if you continue to use the bar-midpoints of the call with (space=0), and you increase space, the ticks and labels will group at the left-hand side.
Below, I illustrate this with your data limited to 3 months in 2017.
In the top layer 3 barplots are drawn with space equal to 0.0, 0.5 and 2.0. The information used to calculated the location of ticks and labels is recalculated and saved at every plot.
In the bottom layer, the same 3 barplots are drawn, but the information used to draw the ticks and labels is only created with the first plot (space=0.0)
# Subset for NEW start for illustration of space and bp
start2 <- as.Date("01/10/2017", "%d/%m/%Y")
df2 <- subset(df, index(df)>=start2)
### get index of ts in month format, define ticks and labels
index_y2 <- format(index(df2), "%m")
at_tick2 <- which(!duplicated(index_y2))
labels2 <- index_y2[!duplicated(index_y2)]
par(mfrow = c(2,3))
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.0, main ="Space = 0.0")
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.5, main ="Space = 0.5")
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 2.0, main ="Space = 2.0")
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
### the lower layer
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.0, main ="Space = 0.0")
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.5, main ="Space = 0.5")
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 2.0, main ="Space = 2.0")
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
par(mfrow = c(1,1))
Have a look here:
Top layer: bp recalculated every time
Bottom layer: bp space=0 reused
Cutting and pasting the commands in your console may illustrate the effects better than the pic above.
I hope this helps.
You could use the axis function, I used match to obtain the indices of the dates on the axis:
space=1
#Plot bars but without x-axis
barplot(df[,2], names.arg=format(index(df), "%Y"), ann=FALSE, bty="n", tck=-0, xaxt="n",
col=1:1, border=NA, space=space); title(main="Example chart", ylab="y-axis")
# Set x-axis parameters
x_min <- min(index(df))
x_max <- max(index(df))
#Add x-axis
axis(1, at=match(seq(as.Date(x_min), x_max, "years"),index(df))*(1+space),
labels = format(seq(as.Date(x_min), x_max, "years"),"%Y"),lwd=0)
Hope this helps!

Plotting in R using plot function

I am trying to plot few graphs using loops. I am now describing in details.
First I have a function which is calculates the y-variable (called effect for vertical axis)
effect<- function (x, y){
exp(-0.35*log(x)
+0.17*log(y)
-0.36*sqrt(log(x)*log(y)/100))
}
Now I run the following code and use the option par to plot the lines in the same graph. I use axis=FALSE and xlab="" to get a plot without labels. I do this so that my labels are not re-written each time the loop runs and looks ugly.
for (levels in seq(exp(8), exp(10), length.out = 5)){
x = seq(exp(1),exp(10), length.out = 20)
prc= effect(levels,x)
plot(x, prc,xlim = c(0,max(x)*1.05), ylim=c(0.0,0.3),
type="o", xlab = "",ylab = "", pch = 16,
col = "dark blue", lwd = 2, cex = 1, axes = F)
label = as.integer(levels) #x variable
text(max(x)*1.03,max(prc), label )
par(new=TRUE)
}
Finally, I duplicate the plot command this time using the xlab and ylab options
plot(x, prc, xlab = "X-label", ylab = "effect",
xlim = c(0,max(x)*1.05), ylim = c(0,0.3),
type="l", col ='blue')
I have several other plots in the similar lines, using complex equations. I have two questions:
Is there an better option to have the same plot with smoother lines?
Is there an easier option with few lines to achieve the same, where I can place the texts (levels) for each line on the right with white background at the back?
I believe working with the plot function was tedious and time consuming. So, I have finally used ggplot2 to plot. There were several help available online, which I have used.

Resources