I want to squeeze (narrow the gap) between the yellow line and the rest of the graph in the basic r plot through having different levels of y-axis labels. How can I do that?
my code is as follows:
Site <- subset(data, Sites == "Bx")
plot(SiteB$value,xlim = c(1,18),ylim=c(4,99.5),xlab="",ylab="",lwd=2,type = "n", asp = NA)
lines(SiteB$value,SiteB$A,type="l", col="orange",lwd=2)
lines(SiteB$value,SiteB$D, type="l", col="purple",lwd=2)
lines(SiteB$value,SiteB$G,type="l", col="blue",lwd=2)
lines(SiteB$value,SiteB$L,type="l",col="red",lwd=2)
lines(SiteB$value,SiteB$M,type="l", col="black",lwd=2)
#lines(SiteB$value,SiteB$S, type="l", col="magenta",lwd=2)
lines(SiteB$value,SiteB$T,type="l",col="green",lwd=2)
Related
"R version 4.0.3 (2020-10-10)"
I have a some time-series data where I am trying to look at the change in consumption over time. Here is a reprex.
set.seed(1)
date <- seq(as.POSIXct('2010-01-01'),as.POSIXct('2010-04-10'),by=86400)
Consumption <- rnorm(99)
Data <- data.frame(date,Consumption)
plot(Data$Consumption~Data$date,type='l') # X-axis labels and ticks not printing
par(yaxt='n')
axis(side = 2,at=seq(-3,3,0.5),labels = seq(-3,3,0.5)) # This works on the first plot on the y axis
plot(Data$date~Data$Consumption,type='l') # X-axis refusing to print despite assigning it.
par(xaxt='n')
axis(side = 1,at=seq(-3,3,0.5),labels = seq(-3,3,0.5)) # This works on the first plot
The graph outputted in the initial plot() is exactly what I want except for the fact it doesn't have any labels for the x-axis.
I am using Base Plotting for an assignment rather than everyday use and would usually use ggplot.
I have been trying to figure out why the x-axis is not plotting. Initially I thought the problem was with the date variable and tried cleaning it up with lubridate::ymd(). However when I started making the above reprex for the purpose of this question it is clear to the X-axis labels and ticks as whole is not printing. In the second plot I put the consumption variable on the x-axis. I was surprised to find that the date is printing neatly on its own on the Y-axis.
What am I doing wrong?
When you want more control over what happens with axis labels and title, you could create them manually. So, first produce a plot without title and label. Then, create them manually with axis() and mtext(). In the process, you may increase the room at the bottom of the plot with par(mar=...). Finetuning is done with arguments like las, cex.axis, and line. And at the end, you reset mar to its old values.
You could use the code below to get more detailed X-axis labels
### format to day (probably not the best way to do this)
Data$date2 <-format(Data$date, "%d%b")
Data$date2 <- as.Date(Data$date2, format = "%d%b")
### increase room at bottom of the plot for X-axis title
### the labels will eat up space, if we do nothing it will be a mess
### set title with mtext later
par(mar = c(7,4,4,2))
### plot without X-axis labels (xaxt) and title (xlab)
### work with "at" and "labels" in axis-function
### rotate labels 90° (las) an reduce font (cex.axis)
### put title 5 lines below graph (line)
###
### Remark: the graph window has to be big enough
plot(Data$Consumption ~ Data$date, type= "l", xaxt = "n", xlab = NA)
axis(side = 1, at = Data$date, labels = Data$date2, las = 2, cex.axis=.75)
mtext(side = 1, text = "Date", line = 5)
This yields the following graph:
ALTERNATIVE
ticks and labels for every 7th item
per7 <- seq(1, 99, 7)
plot(Data$Consumption ~ Data$date, type= "l", xaxt = "n", xlab = NA)
axis(side = 1, at = Data$date[per7], labels = Data$date2[per7], las = 2, cex.axis=.75)
mtext(side = 1, text = "Date", line = 5)
### reset mar
par(mar = c(5,4,4,2))
which gives the following picture:
Please let me know whether this is what you wanted.
There are two issues I can see readily:
change: Consumption <- rnorm(99) to Consumption <- rnorm(100) to
match date column.
The problem is with 'par'. When there are multiple plots within a chunk, unlike ggplot, plot does not handle properly. Remove par and run the below it should work
set.seed(1)
date <- seq(as.POSIXct('2010-01-01'),as.POSIXct('2010-04-10'),by=86400)
Consumption <- rnorm(100)
Data <- data.frame(date,Consumption)
plot(Data$Consumption~Data$date,type='l')
plot(Data$date~Data$Consumption,type='l')
Please note whenever you define par and when you run each plot in two different chunks, the labels will display properly. You will not have any issue. But when you plot both the charts in a single chunk, you will always have problem if you have par.
I'm plotting a survival curve with the survival library, and I haven't found any way to change the breaks range.
For example:
library(survival)
temps <- c(5,15,25,30,18,16,38,40,40,40,40,40,40,40,40,40)
deces <- c(1,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0)
plot(survfit(Surv(temps,deces)~1))
Gives us this plot:
If I want, I can change the range of the whole axis with xlim=c(), the scale of abscissa numbers with xscale.
But the x breaks ranges will always stay at every 5 or 10 units (10,20,30,40).
It's impossible to change them to 12 for example, as I want (12, 24,36,...) because they should represent months.
Is this possible to change them? Or do I have to use the survminer library?
To customized the axes, save the survfit object and plot it with graphics parameter xaxt = "n", meaning, no x axis. Then plot the x axis with axis().
library(survival)
temps <- c(5,15,25,30,18,16,38,40,40,40,40,40,40,40,40,40)
deces <- c(1,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0)
sv <- survfit(Surv(temps, deces) ~ 1)
plot(sv, xaxt = "n")
axis(1, at = seq(0, max(temps) + 12, by = 12))
I'm trying to use base R (and would like to stick to it for this problem) to plot a specific portion of a dataset.
My example data looks like below:
x <- c(1:100)
y <- sort(runif(100, min=0, max=1000))
When I plot this with plot(x,y, type='l'), I get a plot with a y axis that shows 0 to 1000. However, when I plot only a specific x range, my y axis still shows 0 to 1000. I would like to zoom in to reduce the y axis range.
For example,
plot(x,y, type='l', xlim=c(40,60))
plot(x,y, type='l', xlim=c(80,90))
both produces plots with a y axis that ranges c(0,1000). But I'd like to zoom in so that the y axis range for the first plot is something like c(300,700) and that for the second plot is c(700,1000). (300, 700 and 1000 are all arbitrary numbers just to illustrate the purpose to really zoom into the plot). Is there a way to do this without setting specific ylim?
I'd like to avoid using ylim because I'm plotting and saving in a for loop and I can't write a ylim that is suitable for all plots. I've thought of doing something like ylim = max(y)*1.5, but again, since I'm cutting the y values off based on xlim, this doesn't help with zooming in whenever xlim changes.
Subset the relevant data and plot that
lower = 40
upper = 60
ind = which(x >= lower & x <= upper)
plot(x[ind], y[ind], type = "l")
In R, I have n-number of barplots of this form
y = rnorm(500)
y = matrix(y,100,5)
y.means = abs(apply(y,2,mean))
barplot(y.means, names.arg=1:5)
I want these to share the same x-axis. How is that done without using any extra libraries?
With a little bit of stuffing about and taking advantage of saving barplot positions this is possible:
vals <- cbind(y.means, newone=y.means)
bp <- barplot(vals, beside=TRUE, plot=FALSE)
barplot(unname(vals), beside=TRUE, names.arg=c(1:5, 1:5) )
axis(1, at=colMeans(bp), labels=colnames(vals), line=2, lty=0)
I have an xy plot in lattice on which I'm showing four different things. The plot looks like this right now. The values for pink line range from 1 to 15000, however, values for other lines range from 20 to 300. This is why all lines other than pink seem static. However, there are fluctuations in them but I feel the graph isn't showing them property because of yaxis. Is there a way I can shorten the yaxis such that the graph is better representing the other lines as well?
This is how it looks when I don't plot the pink line all together. This shows there are fluctuations which I'd like to show.
If you can use the base package instead of lattice it is quite simple. The code below is vastly simplified from one of my own plots. You will have to fiddle a little with it to add two more lines.
line description
1,2 plot from a data frame. ylab will be on side 2 (left) scale will be automatically determined from the data
3 start a second plot
4 plot from a data frame, use axes=FALSE, xlab=NA, ylab=NA
5 create the axis for side 4 (right) scale will be automatically determined from the data
6 make the ylab for side 4
1 plot(df[c(4,5)], type = "s", col = "blue", main = "Battery Life",
2 xlab="minutes", ylab="percent")
3 par(new=TRUE)
4 plot(df[c(4,6)], type = "s", col = "red", axes = FALSE, xlab = NA, ylab = NA)
5 axis(side = 4)
6 mtext(side = 4, line = 3, "Slope ( minutes)")
You can use the latticeExtra package to create a graph with 2 separate y-axis.
As the comments suggest, I would rather create 2 separate plots. It's a cleaner solution.
As an alternativ: maybe you could add a conditioning variable to your data ("magnitude" or so) which groups your data into suitable chunks. Then you could present your data as shown below.
library("lattice")
library("latticeExtra")
dat1 <- data.frame(x=1:100, y1=rep(1:10,10), y2=rep(100:91,10))
dat2 <- data.frame(x=1:200, y=c(rep(1:10,10), rep(100:91,10)),
z=c(rep("small",100), rep("huge",100)))
p1 <- xyplot(y1~x, data=dat1, type="l")
p2 <- xyplot(y2~x, data=dat1, type="l")
doubleYScale(p1, p2) # 2 y-axis: bad
xyplot(y ~ x | z, data=dat2, type="l", scales="free") # 2 plots: good