I am trying to overlay two graphs onto the same axes. I set up my axes limits and labels first, but then when I plot the graphs they resize and are not on my pre-determined scale.
I have pared my code down into a simple example. You can see that 100 and 10 are showing up at the same place on the y axis. Please help!
x<- 1:3
y1<- c(100, 75, 20)
y2<- c(10, 9, 4)
plot.new()
plot(0, type="n",
xlim=c(1,max(x)), ylim=c(0,max(y1,y2)),
xlab= "x label", ylab= "y label", main= "This stupid graph doesn't work!")
par(new=TRUE)
par(new=TRUE)
plot(x,y1, type="b", pch=19, col="orchid",
axes=FALSE, ann=FALSE)
par(new=TRUE)
plot(x,y2, type="b", pch=19, col="slateblue",
axes=FALSE, ann=FALSE)
legend("topright",c("This is","Annoying"), col=c("orchid","slateblue"), pch=19)
You want to use lines to add the second line, meanwhile making sure that ylim allows for all the values being plotted to fit within the plotting region.
plot(y1 ~ x, ylim = range(c(y1, y2)), xlab = "x label", ylab = "y label",
main = "This one might work!", type = 'b', pch = 19, col = "orchid")
lines(y2, type = 'b', pch = 19, col = 'slateblue')
legend("topright", c("R is", "awesome"), col = c("orchid","slateblue"), pch = 19)
Related
I used plot.new to combine two different graphs on R with this code:
par(mar=c(4, 4, 3, 5))
plot(d1, col="grey", yaxt="n", xlab="", ylab = "", ylim(0, 1.5), type = "h", fill ="grey")
axis(4, at=seq(0,1.5, by=0.05), col="grey", col.axis="grey")
mtext("Fn_1", side=4, line=2.5, col="grey")
mtext("Sqrt Insolation", side=1, line=2.5, col="black")
par(new=TRUE)
plot(h, axes=FALSE, type = "l", xlab = "", ylab="")
axis(2, ylim=c(-0.10, 0.1), at=seq(-0.10, 0.1, by=0.05), col="black", col.axis="black") mtext("Fn_2", side=2, line=2.5, col="black")
This is my result
https://i.stack.imgur.com/umCWu.png
I want to have a y axis like ylim = c (-0.10,1.5) and adjust the scale (h curb is way too big with this scale ..)
OR two y axes like here, but align on 0 with the same scale.
I tried to change the criteria of my axes but they seem to adjust automatically to make sense with the minimum and maximum of my data. I want to have one y axis as ylim = c(-0.10,1.5) and adjust scale (h courb is way too large with this actual scale..)
Can someone help me ?
Thank you very much
I have the following function
C=15
S=seq(0,12,.1)
pA=1
pS=0.5
A <- function(S) (C/pA)-(pA/pS)*S
plot (S, A(S), type="l", col="red", ylim=c(0,15), xlim=c(0,15), xlab="S", ylab="A")
text(8, 11.5, "Function", col = "red", cex=.9)
text(11, 10.2, expression(A==frac(C,p[S])-frac(p[A],p[S])%.%S), cex=.9, col = "red")
grid()
How can I scale the axis so that I can "zoom out" a bit. I am looking for a function similar to ylim but where I could say: ylim=c(0,15, by=1).
Update
It seems your "zoom out" is meant for the grid lines, not for the axis or anything. I'll keep the previous answer below, but this should address it, I think.
# no change yet
plot (S, A(S), type="l", col="red", ylim=c(0,15), xlim=c(0,15), xlab="S", ylab="A")
text(8, 11.5, "Function", col = "red", cex=.9)
text(11, 10.2, expression(A==frac(C,p[S])-frac(p[A],p[S])%.%S), cex=.9, col = "red")
# no call to grid, since we want to control it a little more precisely
abline(h = seq(0, 15), col = "lightgray", lty = "dotted", lwd = par("lwd"))
abline(v = seq(0, 15, by = 5), col = "lightgray", lty = "dotted", lwd = par("lwd"))
You can do just abline(h=seq(...)) and not set col=, lty=, or lwd=, but realize that abline's default values are different from grid's defaults. I used those values to mimic grid's look and feel.
Old answer
I think you mean to change the y axis labels, not the y axis limits (which is all that ylim= can effect).
Using base R graphics:
plot (S, A(S), type="l", col="red", ylim=c(0,15), xlim=c(0,15), xlab="S", ylab="A",
yaxt = "n") # this is new
text(8, 11.5, "Function", col = "red", cex=.9)
text(11, 10.2, expression(A==frac(C,p[S])-frac(p[A],p[S])%.%S), cex=.9, col = "red")
grid()
axis(2, at = 1:15, las = 2)
Explanation:
plot(..., yaxt = "n") means to not plot the y-axis ticks and labels, see ?par.
axis(...) adds an axis to a side. By itself, it will just add a default axis.
at= sets where the ticks and labels are placed.
labels= sets what to put at each tick. If absent (like it is above), it just prints the at value.
las=2 rotates the number so that it is perpendicular to the axis line. I did this to show more of the numbers, otherwise they will mask a bit more.
While this shows every-other, that is affected by the size of the canvas; if you do the same plot in full-screen, it'll show every number.
I want the y axis in regular plot() function to start at the bottom of the plot area similar to hist() function. In other words I would like to have zeros of both axis at the same level. Here is my working example
set.seed(1)
data <- data.frame(
type = as.factor(sample(c('A', 'B', 'C'), size = 100, replace = T)),
value = rexp(100, 1/3)
)
plot(data$type)
par(new=TRUE)
plot(tapply(data$value, data$type, mean),
xaxt="n", yaxt="n", xlab="", ylab="",
xlim=c(0.55,3.45), ylim=c(0, 5), bty='n', pch=24, bg='black')
axis(4)
I tried to use parameter yaxs = 'i' in the plot() function, but it moved the axis too low. Is there any solution to this?
Find one variant
set ylim in first plot
try
plot(data$type, yaxs = 'i',ylim=c(0,max(apply(data, 2, table)[[1]])))
par(new=TRUE)
plot(tapply(data$value, data$type, mean),
xaxt="n", yaxt="n", xlab="", ylab="",
xlim=c(0.55,3.45), ylim=c(0, 5), bty='n', pch=24, bg='black',yaxs = 'i')
axis(4)
axis(1,at=c(0,5)) #only for show that one lvl
I am trying to create a plot that shows two different time scales on the x-axis. The problem is that the two time scales have a complicated relationship.
I would like to show weather data by the day of year and by the thermal units. Thermal units are the accumulation of the mean temperatures of each day. Some days we get a lot of thermal units, some days not so many. I fit a spline to the relationship between day of year and thermal units and used that to predict thermal unit values for each day. So I do have a nice dataset with the following headers: day of year (day), thermal units (gdd), temperature (temp), precipitation (precip).
I created the following figure (may have to open in new window):
with this code:
pdf(file="Climate 2010.pdf", family="Times")
par(mar = c(5,4,4,4) + 0.3)
plot(cobs10$day, cobs10$precip, col="white", type="h", yaxt="n", xaxt="n", ylab="",
xlab="")
axis(side=3, col="black", labels=FALSE)
at = axTicks(3)
mtext(side = 3, text = at, at = at, col="black", line = 1, las=0)
mtext("Day of Year", side=3, las=0, line = 3)
par(new=TRUE)
plot(cobs10$gdd, cobs10$temp, type="l", col="red", yaxt="n", ylab="", xlab="Thermal
Units")
axis(side=2, col='red', labels=FALSE)
at= axTicks(2)
mtext(side=2, text= at, at = at, col = "red", line = 1, las=0)
mtext("Temperature (C)", side=2, las=0, line=3)
par(new=TRUE)
plot(cobs10$gdd, cobs10$precip, type="h", col="blue", yaxt="n", xaxt="n", ylab="",
xlab="")
axis(side=4, col='blue', labels=FALSE)
at = axTicks(4)
mtext(side = 4, text = at, at = at, col = "blue", line = 1,las=0)
mtext("Precipitation (cm)", side=4, las=0, line = 3)
dev.off()
This is exactly what I want, but I realized the x-axis scales are linear here, and they should not be. I put the top x-axis in by making my precipitation data white and writing over it. See what happens when I make it green:
It's obvious things don't match up. So how can I make the two axes in scale with eachother?
Here's the little dataframe I have been using where the time units are matched up by predicting:
cobs10.txt. "gdd" is thermal units
EDIT: Here is some new code that doesn't use par(new=TRUE):
par(mar = c(5,4,4,4) + 0.3)
plot(cobs10$gdd, cobs10$temp, type="l", col="red", yaxt="n", xlab="", ylab="",
ylim=c(-25, 30))
lines(cobs10$gdd, cobs10$precip, type="h", col="blue", yaxt="n", xlab="", ylab="")
axis(side=3, col="black", at=cobs10$gdd, labels=cobs10$day)
want<-(c(1, 130, 150, 170, 190, 210, 230, 250, 270, 360))
mtext(side = 3, text = want, at = want, col="black", line = 1, las=0)
mtext("Day of Year", side=3, las=0, line = 3)
axis(side=2, col='red', labels=FALSE)
at= axTicks(2)
mtext(side=2, text= at, at = at, col = "red", line = 1, las=0)
mtext("Temperature (C)", side=2, las=0, line=3)
axis(side=4, col='blue', labels=FALSE)
at = axTicks(4)
mtext(side = 4, text = at, at = at, col = "blue", line = 1,las=0)
mtext("Precipitation (cm)", side=4, las=0, line = 3)
It is almost never a good idea to use par(new=TRUE), it causes more problems than it solves.
You should decide which x axis units you want to use, days or thermal units and create the initial graph using that unit, then use functions like points or lines to add any additional points or lines to the existing graph using the existing units. You can then use the axis function to add another axis, use the original units for the at argument, but then the conversion to the other units for the labels (you need to decide if you want the locations of the ticks to match the original units, or be in locations that give pretty values for the converted units).
I have 3 sets of data that I am trying to plot on a single plot. The first data set x values range from ~ 1 to 1700 whereas the other two data sets x values are less than 20. Therefore I want to plot them on a log axis to show variations in all the data sets. However I do not want to transform the data as I want to be able to read the values off the graph. The x axis labels I would like are 1, 10, 100 and 1000 all equally spaced. Does anyone know how to do this? I can only find examples where the data is log as well as the axis. I have attached the code I am currently using below:
Thanks in advance for any help given.
Holly
Stats_nineteen<-read.csv('C:/Users/Holly/Documents/Software Manuals/R Stuff/Stats_nineteen.csv')
attach(Stats_nineteen)
x<-Max
x1<-Min
x2<-Max
y1<-Depth
y2<-Depth
par(bg="white")
par(xlog=TRUE)
plot(x2,y1, type="n", ylim=c(555,0), log="x", axes=FALSE, ann=FALSE)
box()
axis(3, at=c(1,10,100,1000), label=c(1,10,100,1000), pos=0, cex.axis=0.6)
axis(1, at=c(1,10,100,1000), label=c(1,10,100,1000), cex.axis=0.6)
axis(2, at=c(600,550,500,450,400,350,300,250,200,150,100,50,0), label=c
(600,"",500,"",400,"",300,"",200,"",100,"",0), cex.axis=0.6)
mtext("CLAST SIZE / mm", side=3, line=1, cex=0.6, las=0, col="black")
mtext("DEPTH / m", side=2, line=2, cex=0.6, las=0, col="black")
grid(nx = NULL, ny = NULL, col = "lightgray", lty = "solid",
lwd = par("lwd"), equilogs = TRUE)
par(new=TRUE)
lines(x1,y1, col="black", lty="solid", lwd=1)
lines(x2,y2, col="black", lty="solid", lwd=1)
polygon(c(x1,rev(x2)), c(y1,rev(y2)), col="grey", border="black")
par(new=TRUE)
plot(x=Average,y=Depth, type="o",
bg="red", cex=0.5, pch=21,
col="red", lty="solid",
axes=FALSE, xlim=c(0,1670), ylim=c(555,0),
ylab = "",xlab = "")
par(new=TRUE)
plot(x=Mode,y=Depth, type="o",
bg="blue", cex=0.5, pch=21,
col="blue", lty="solid",
axes=FALSE, xlim=c(0,1670), ylim=c(555,0),
ylab = "",xlab = "")
You can do this in ggplot using scale_x_log
so something like:
myplot <- ggplot( StatsNinetee,
aes (x = myResponse,
y = myPredictor,
groups = myGroupingVariable) ) +
geom_point() +
scale_x_log()
myplot
also, avoid attach() it can give odd behavior.